你不知道的 JS 读书笔记(三)-- this/原型对象
2017年11月22日预计阅读需要 6 分钟
this 绑定规则
默认绑定
严格模式下绑定到undefined,否则绑定到全局对象
function foo () {
console.log(this.a);
}
var a = 2;
foo(); // 2
隐式绑定
由上下文对象调用,绑定到该上下文对象
function foo () {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
};
obj.foo() // 2
// 隐式丢失----
var a = "oops, global";
setTimeout(obj.foo, 100) // "oops, global"
// 隐式赋值,丢失上下文
显式绑定:apply,call.硬绑定:bind
new 绑定
function foo () {
this.a = a;
}
var bar = new foo(2);
console.log(bar.a); // 2
优先级
new 绑定 > 显式绑定(apply,call),硬绑定(bind) > 隐式绑定 > 默认绑定
tip
Object.create(null)
类似 {}
,但是前者不会创建 Object.prototype
这个委托,所以它比 {}
“更空”
意义:
Object.create(null)
用法更安全,Object.create
会创建一个新的空对象,并把新对象内部的[[Prototype]]
关联到你指定的对象,这里就导致新对象的Object.prototype
为null
。那么任何对于this
的使用都会被限制在这个空对象中,不会对全局对象(整条原型链)产生任何影响
ES6 中的箭头函数不会使用四条标准的绑定规则,而是根据当前的词法作用域来决定 this,和 self = this
机制一样
基本类型
string number boolean null undefined
内置对象
String Number Boolean Object Function Array Date RegExp Error
var strPrimitive = "I am a string";
typeof strPrimitive; // "string"
strPrimitive instanceof String; // false
var strObject = new String( "I am a string" );
typeof strObject; // "object"
strObject instanceof String; // true
复制对象
// someObj 需要可以被序列化为一个 JSON 字符串并且可以根据这个字符串解析出一个结构和值完全一样的对象
var newObj = JSON.parse( JSON.stringify( someObj ) );
// Object.assign(..) 属于浅复制,遍历键名,并赋值
属性描述符
// 查看属性描述符信息
var myObject = { a:2 };
Object.getOwnPropertyDescriptor( myObject, "a" );
// {
// value: 2,
// writable: true,
// enumerable: true,
// confgurable: true
// }
// 设置属性描述符
var myObject = {};
Object.defineProperty( myObject, "a", {
value: 2,
writable: true, // 是否可以修改属性的值
configurable: true, // 属性是否可配置,改为false是单向操作
enumerable: true // 是否可枚举,如:for..in,forEach等
});
myObject.a; // 2
get set
var myObject = {
// 给 a 定义一个 getter
get a() {
return this._a_;
},
// 给 a 定义一个 setter
set a(val) {
this._a_ = val * 2;
}
};
myObject.a = 2;
myObject.a; // 4
存在性
var myObject = { a:2 };
("a" in myObject); // true
("b" in myObject); // false
myObject.hasOwnProperty( "a" ); // true
myObject.hasOwnProperty( "b" ); // false
in
操作符会检查属性是否在对象及其 [[Prototype]]
原型链中。 相比之下,hasOwnProperty(..)
只会检查属性是否在 myObject
对象中, 不会检查 [[Prototype]]
链。
遍历
for..in
循环可以用来遍历对象的可枚举属性列表(包括 [[Prototype]]
链)
ES6 增加了一种用来遍历数组的 for..of
循环语法(如果对象本身定义了迭代器的话也可以遍历对象)