另一方面,__proto__
属性,通常读作 "dunder proto",存在于每一个 JavaScript 对象中 。在 JavaScript 中,除了原始类型外,一切都可以被视为对象 。每个这样的对象都有一个原型 , 该原型作为对另一个对象的引用 。__proto__
属性简单地是对这个原型对象的引用 。
当你试图访问对象上的一个属性或方法时 , JavaScript 会进行查找过程来找到它 。这个过程主要涉及两个步骤:
对象的自有属性:JavaScript 首先检查对象自身是否直接拥有所需的属性或方法 。如果在对象内找到了该属性 , 则直接访问和使用 。原型链查找:如果在对象自身没有找到该属性,JavaScript 将查看对象的原型(由 __proto__
属性引用)并在那里搜索该属性 。这个过程会递归地沿着原型链进行,直到找到该属性或直到查找达到 Object.prototype
。如果在 Object.prototype
中甚至没有找到该属性,JavaScript 将返回 undefined
,表示该属性不存在 。
4-作用域当编写 JavaScript 代码时,理解作用域的概念非常重要 。作用域指的是变量在代码的不同部分的可访问性或可见性 。下面我们通过一个代码片段来更仔细地了解这个概念:
function foo() { console.log(a);}function bar() { var a = 3; foo();}var a = 5;bar();
代码定义了两个函数 foo()
和 bar()
,以及一个值为5
的变量 a
。所有这些声明都发生在全局作用域中 。在bar()
函数内部,声明了一个变量a
并赋值为 3
。那么当bar()
函数被调用时,你认为会输出哪个值的a
?
当JavaScript引擎执行这段代码时,全局变量a
被声明并赋值为5
。然后调用了bar()
函数 。在bar()
函数内部,声明了一个局部变量a
并赋值为3
。这个局部变量a
与全局变量a
是不同的 。之后,从bar()
函数内部调用了foo()
函数 。
在foo()
函数内部,console.log(a)
语句试图输出变量a
的值 。由于在foo()
函数的作用域内没有定义局部变量a
,JavaScript会查找作用域链以找到最近的名为a
的变量 。
现在,我们来解答JavaScript将在哪里搜索变量a
的问题 。它会查找bar
函数的作用域吗,还是会探索全局作用域?事实证明,JavaScript会在全局作用域中搜索 , 这种行为是由一个叫做词法作用域的概念驱动的 。
词法作用域是指函数或变量在代码中被编写时的作用域 。当我们定义了foo
函数,它被赋予了访问自己的局部作用域和全局作用域的权限 。这一特性在我们无论在哪里调用foo
函数时都是一致的,无论是在bar
函数内部还是在其他模块中运行 。词法作用域并不是由我们在哪里调用函数来决定的 。
最终结果是,输出始终是全局作用域中找到的a
的值,在这个例子中是5
。
然而,如果我们在bar
函数内部定义了foo
函数,情况就会有所不同:
function bar() { var a = 3; function foo() { console.log(a); } foo();}var a = 5;bar();
在这种情况下,foo
的词法作用域将包括三个不同的作用域:它自己的局部作用域 , bar
函数的作用域,以及全局作用域 。词法作用域是由你在源代码中放置代码的位置在编译时决定的 。
当这段代码运行时,foo
位于 bar
函数内部 。这种安排改变了作用域的动态 。现在,当foo
试图访问变量a
时 , 它首先会在自己的局部作用域内进行搜索 。由于没有找到a
,它会扩大搜索范围到bar
函数的作用域 。果然,那里存在一个值为3
的a
。因此,控制台语句将输出3
。
5-对象强制类型转换const obj = { valueOf: () => 42, toString: () => 27};console.log(obj + '');
一个引人入胜的方面是探究JavaScript如何处理对象转换为基本值,例如字符串、数字或布尔值 。这是一个有趣的问题,测试你是否了解对象的强制类型转换 。
推荐阅读
- 每个高级前端工程师都应该知道的前端布局
- Vercel推出的前端AI工具v0,会改变前端么?
- 靶向药治疗
- 什么是靶向药
- 高级职称有哪些 计算机高级职称有哪些
- 一行代码禁止用户调试前端代码!
- 必知!前端测试对你的网站有哪些影响?
- 前端容器化实践
- 60岁章小蕙生图曝光,身材微胖也不减高级范,珠圆玉润一脸“旺夫相”
- 48岁周迅彻底放飞自我!穿中式大妈裙走机场,本以为很老土,但却随性又高级