new
Javascript中的new
运算符是用来实例化一个类,从而在内存中分配一个实例对象。
在javascript中, 通过new可以产生原对象的一个实例对象,而这个实例对象继承了原对象的属性和方法。因此,new存在的意义在于它实现了javascript中的继承,而不仅仅是实例化了一个对象!
一个模拟new实现过程的代码如下(注意仅仅是模拟其实现过程,并不能替代new!):
function createNew(fn)
{
var obj = {};
obj.__proto__ = fn.prototype;
var result = fn.apply(obj, Array.prototype.slice.call(arguments, 1));
return typeof result === 'object'? result : obj;
}
以上代码的过程分析如下:
- 创建一个空对象
obj
; - 把
obj
的__proto__
(不同浏览器实现不同)指向fn
的原型prototype
,此时便建立了obj对象的原型链:obj
->fn.prototype
->Object.prototype
->null
; - 以
obj
为this
执行fn
; - 观察第3步返回的返回值,如果无返回值或者返回一个非对象值,则将
obj
返回作为新对象;否则会将返回值作为新对象返回。
测试:
function Animal(name)
{
this.name = name;
}
Animal.prototype.showName = function()
{
console.log(this.name);
};
var cat = createNew(Animal, 'cat');
cat.showName(); // cat
var dog = new Animal('dog');
dog.showName(); // dog
instanceof
instanceof
操作符用于判断:某个对象是否存在另外一个要检测对象的原型链上。
A instanceof B
内部判断逻辑是:沿着A的原型链一直往上找,如果发现A的隐式原型和B的原型相同,那么就返回true
。
function myInstanceof(A, B) {
while(A.__proto__ != null) {
if(A.__proto__ === B.prototype) return true;
A = A.__proto__;
}
return false;
}
myInstanceof(/1/g, RegExp); // true
myInstanceof(/1/g, Object); // true
myInstanceof(new Date(), Date); // true
20170726更新
貌似有特殊情况,有待研究:
'abc'.__proto__ === String.prototype; // true
'abc' instanceof String; // false
new String('abc') instanceof String; // true