在 lib/sdk.js 中
if (!(this instanceof ChainSDK)) {
return new ChainSDK(options);
}
先说结论:这里通过 this instanceof xxx 来判断有没有用 new 关键词调用。
那么,为什么可以这么判断呢?我们分别了解一下 this 和 instanceof 的用法。
this
在 JavaScript 中,this 是动态绑定,或称为运行期绑定的,它可以是全局对象、当前对象或者任意对象,这取决于函数的调用方式。函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用,和使用 apply 或 call 调用。
具体的使用方式请移步至:浏览器 JavaScript 中的 this 的使用,具体我就不展开赘述了。
instanceof
instanceof 有几个用法:
1、通常使用 instanceof 就是判断一个实例是否属于某种类型,比如:
function Foo(){}
var foo = new Foo();
console.log(foo instanceof Foo)
2、更重要的一点是 instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型。例如:
function Aoo(){}
function Foo(){}
Foo.prototype = new Aoo();
var foo = new Foo();
console.log(foo instanceof Foo)
console.log(foo instanceof Aoo)
上面的代码中是判断了一层继承关系中的父类,在多层继承关系中,instanceof 运算符同样适用。
3、ECMAScript 中 instanceof 的定义
11.8.6 The instanceof operator The production RelationalExpression:
RelationalExpression instanceof ShiftExpression is evaluated as follows:
1. Evaluate RelationalExpression.
2. Call GetValue(Result(1)).
3. Evaluate ShiftExpression.
4. Call GetValue(Result(3)).
5. If Result(4) is not an object, throw a TypeError exception.
6. If Result(4) does not have a [[HasInstance]] method,
throw a TypeError exception.
7. Call the [[HasInstance]] method of Result(4) with parameter Result(2).
8. Return Result(7).
15.3.5.3 [[HasInstance]] (V)
Assume F is a Function object.
When the [[HasInstance]] method of F is called with value V,
the following steps are taken:
1. If V is not an object, return false.
2. Call the [[Get]] method of F with property name "prototype".
3. Let O be Result(2).
4. If O is not an object, throw a TypeError exception.
5. Let V be the value of the [[Prototype]] property of V.
6. If V is null, return false.
7. If O and V refer to the same object or if they refer to objects
joined to each other (section 13.1.2), return true.
8. Go to step 5.
翻译成 JavaScript 代码如下所示:
function instance_of(L, R) {
var O = R.prototype;
L = L.__proto__;
while (true) {
if (L === null)
return false;
if (O === L)
return true;
L = L.__proto__;
}
}
从代码中我们可以看到,instanceof 是比较左侧的 __proto__ (隐式原型)和右侧的 prototype (显示原型)是否相等,如果不相等,取左侧 __proto__ 的 __proto__ ,依次循环比较,直到取到 Object.prototype.__proto__ 即 null 为止。 关于 __proto__ 和 prototype 请移步至:原型与原型链
回到主题
this instanceof xxx 我们可以这么分解:this.__proto__ 和 xxx.prototype
所以如果用 new 操作符的话,this instanceof xxx 结果为 true 。
|