原型和原型链类似于Java和C#的继承;
首先在慕课网上学习到的5个关于JavaStript原型的规则。
1.所有引用类型(数组,函数,对象)除了null之外,都有对象的特征,都可以自由扩展属性;
2.所有的引用类型,都有__proto__(隐式原型)属性,属性值是一个普通的对象。
3.所有的函数,都有一个prototype(显式原型)属性,属性值是也是一个普通的对象。
4.所有的引用类型(数组,对象,函数),其__proto__属性指向它的构造函数的"prototype"属性.
5.当试图得到一个引用类型的属性时,如果这个引用类型本身没有这个属性,那么他会去它的__proto__(即它的构造函数的prototype中寻找).
五个规则的例子如下:
//1.所有引用类型(数组,函数,对象)除了null之外,都有对象的特征,都可以自由扩展属性;
var obj = {}; obj.a = 100;
var arr = []; arr.a = 10;
var fn = function () {
}
fn.a = 1;
var fn1 = new fn();//创建一个fn的实例
console.log(obj.a);
console.log(arr.a);
console.log(fn.a);
//2.所有的引用类型,都有__proto__(隐式原型)属性,属性值是一个普通的对象。
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
//3.所有的函数,都有一个prototype(显式原型)属性,属性值是也是一个普通的对象。
console.log(fn.prototype);
//下面两个是未定义的
console.log(obj.prototype);//undefined 所以可见Obj和数组是没有显示原型的啦。
console.log(arr.prototype);//undefined
//4.所有的引用类型(数组,对象,函数),其__proto__属性指向它的构造函数的"prototype"属性.
console.log(fn.__proto__ === Function.prototype);//true
console.log(fn instanceof Object);
console.log(fn instanceof Function);
console.log(Function instanceof Object);
console.log(Function.__proto__ === Object.prototype)
console.log(obj.__proto__ === Object.prototype);//true
console.log(arr.__proto__ === Array.prototype);//true
/*----------------------------------------------------------------------------*/
console.log(fn1.__proto__ === fn.prototype);//true fn是fn1的构造函数,所以下面的式子为假.
console.log((fn1.__proto__).__proto__ === Function.prototype);//false
console.log(fn1 instanceof Function);
// console.log(Object.prototype === null);
//5.当试图得到一个引用类型的属性时,如果这个引用类型本身没有这个属性,那么他会去它的__proto__(即它的构造函数的prototype中寻找).
//构造函数:
function Foo(name,age) {
this.name = name;
}
Foo.prototype.alertName=function () {
alert(this.name);
}
//创建示例:
var f = new Foo('zhangsan')
f.printName=function () {
console.log(this.name);
}
//测试:
f.printName();
f.alertName();
console.log(f.__proto__ === Foo.prototype);
console.log(Foo instanceof Function);
但是在这也抛出疑问:
1.在例子的第五点中 f 函数是由Foo函数构造出来的,所以(f instanceof Foo)是true的;
Foo也是又Function函数构造出来的,所以(Foo instantceof Fucntion)是true;
但是(f instanceof Function)确实false;f 的最终的显示原型是Object.这个困惑一直不解。
以下是两个函数的原型链。
// __proto__ _proto__ __proto__
// f -----------> Foo.prototype -----------> Object.prototype -----------> null
// __proto__ __proto__ __proto__
// Foo -----------> Function.prototype -----------> Object.prototype -----------> null
最后推荐个帮助理解的博客。
https://www.cnblogs.com/objectorl/archive/2010/01/11/Object-instancof-Function-clarification.html