typeof null 为 ”object” 诠释
- 差别的对象在底层都示意为二进制,在JavaScript中二进制前三位都为0的话会被推断为object范例,null 的二进制示意都是0,天然前三位都是0,所以实行 typeof null 时,会返回 ”object”。
传统编程言语编译的三个步骤
- 分词/词法剖析
- 剖析/语法剖析
- 代码天生
变量的赋值操纵
- 编译阶段 — 初次编译器会在当前作用域中声明一个变量(变量提拔),假如之前没用声明过。
- 运转阶段 — 运转时引擎会在作用中查找该变量,假如能够找到就会对它赋值(LHS查询。
作用域
- 作用域是一套划定规矩,用于确定在那边以及怎样查找变量。
- 假如查找的目标是对变量赋值,那末就会运用 LHS 查询。
- 假如查找的目标是猎取变量的值,那末就会运用 RHS 查询。
- 不管函数在那里被挪用,也不管它怎样被挪用,它的词法作用域都只由函数被声明时所处的位置决议。
闭包
- 当函数能够记着并接见地点的词法作用域,纵然函数是在当前词法作用域以外实行,这时候就产生了闭包。
this
- this 在任何情况下都不指向函数的词法作用域。
- 在 JavaScript 中作用域确切和对象相似,可见的标识符都是它的属性。
- 然则作用域“对象”没法经由过程 JavaScript 代码接见,它存在 JavaScript 引擎的内部。
- this 是在运转时举行绑定的,并非在编写时绑定,它的上下文取决于函数调 用时的种种前提。
- this 的绑定和函数声明的位置没有任何关系,只取决于函数的挪用体式格局。
- 当一个函数被挪用时,会建立一个运动纪录(偶然也称为实行上下文)。
- 这个纪录会包含函数在那里被挪用(挪用栈),函数的挪用要领,传入的参数等信息。this 就是纪录个中的一个属性,会在函数实行的过程当中用到。
- this 实际上是在函数被挪用时发作的绑定,它指向什么完整取决于函数在那里被挪用。
- 挪用栈 — 就是为了抵达当前实行位置所挪用到的所用函数。
bind()
- 会返回一个硬编码的新函数,它会把参数设置为 this 的上下文并挪用原始函数。
new 操纵符
运用 new 来挪用函数时,会自动实行下面的操纵:
- 建立一个新的空对象;
- 这个对象会被实行[[原型]]衔接;
- 这个新对象会绑定到函数挪用的 this;
- 假如函数没用返回其他对象,那末 new 表达式中的函数挪用会自动返回这个新对象。
推断 this
能够依据下面的递次来举行推断:
函数是不是在 new 中挪用(new绑定)假如是的话,this 是绑定的是新建立的对象。
var bar = new foo();
函数是不是是经由过程 call apply (显现绑定)或许硬绑定挪用,假如是的话,this绑定的是指定的对象。
var bar = foo.call(obj2);
函数是不是在某个上下文对象中挪用(隐式挪用),假如是的话,this绑定的是谁人上下文对象。
var bar = obj.foo();
若果都不是的话,运用默许绑定,假如在严厉形式下,就绑定到 undefined,不然绑定到全局对象上。
var bar = foo();
ES6 新增可计算属性名
var prefix = "foo";
var myObject = {
[prefix + "bar"]: "hello",
[prefix + "baz"]: "world"
}
myObject["foobar"]; // hello
myObject["foobaz"]; // world
in / hasOwnProperty() — 推断某个对象是不是存在某个属性
- in 操纵符会搜检属性是不是在对象及其 [[Prototype]] 原型链中。
- hasOwnProperty() 只会搜检属性是不是在 myObject 对象中,不会搜检 [[Prototype]] 链。
forEach() / every() / sone() — 历数组的值
- forEach() 会遍历数组中的一切值并疏忽回调函数的返回值(疏忽返回值)。
- every() 要领测试数组的一切元素是不是都经由过程了指定函数的测试(返回值是false停止)。
- some() 要领测试是不是至少有一个元素经由过程由供应的函数完成的测试(返回值是true停止)。
for…in — 遍历数组下标/对象可罗列属性
- 不保证 key 递次。
for…of — 遍历可迭代对象的值
- 在可迭代对象上(包含 Array,Map,Set,String,TypedArray,arguments
对象等)上建立一个迭代轮回,挪用自定义迭代钩子自定义的 @@iterator 对象 ,并为每一个差别属性的值实行语句。
var randoms = {
[Symbol.iterator]: function() {
return {
next: function() {
return {
value: Math.random()
};
}
};
}
};
var randoms_pool = [];
for (var n of randoms) {
randoms_pool.push( n );
// 防备无穷运转!
if (randoms_pool.length === 100) break;
}
类的继续和多态
- 多态并不示意子类和父类有关联,子类获得的只是父类的一份副本,类的继续实在就是复制。
属性的设置和屏障
var myObject = {};
myObject.foo = "bar";
- 假如 myObject 对象中包含名为 foo 的一般数据接见属性,这条赋值语句只会修正已有的属性值。
- 假如 foo 不是直接存在于 myObject 中,[[Prototype]] 链就会被遍历,相似 [[Get]] 操纵。
- 假如原型链上找不到 foo,foo 就会被直接添加到 myObject 上。
- 但是,假如 foo 存在于原型链上层,赋值语句 myObject.foo = “bar” 的行动就会有些差别 (而且能够很出人意表)。
- 假如属性名 foo 既出现在 myObject 中也出现在 myObject 的 [[Prototype]] 链上层,那 么就会发作屏障。
- myObject 中包含的 foo 属性会屏障原型链上层的一切 foo 属性,由于 myObject.foo 总是会挑选原型链中最底层的
foo 属性。
转载请说明出处,假如想要相识更多,请搜刮微信民众号:webinfoq。