js原型链
2018-03-29 本文已影响0人
Dargonfly429
目录
- 1.对象的原型和原型链
- 1.1什么是原型
- 1.2查看原型
- 1.3对象的原型链
- 2.使用构造函数
- 2.1 函数的原型链
- 2.2 函数的prototype属性
- 2.3 实例与构造函数的原型链
- Array Function Object关系
1.对象的原型和原型链
1.1 什么是原型?
在java里,面向对象的基本概念是类和对象,用类实例出对象,类之间能够构建继承关系,子类能够调用父类的方法。</br>
在js里,少了一层类的概念,对象之间可以直接形成类似java里继承的关系,子对象可以调用父对象的属性和方法。</br>
js里用“原型”来描述这种关系。</br>
一个对象的proto属性指向他的原型。</br>
1.2 如何查看原型
proto指向对象的原型
var A = {name : 'lili'};
console.log(typeof(A)); //object
console.log(A.__proto__ === Object.prototype);//true
所有对象的原型都指向Object.prototype
1.3 对象原型链
对象的继承中,涉及到三个角色
对象、对象.prpto、Object.prototype
console.log('********************comes B');
var B = {height : 168};
B.__proto__ = A; //手动改下原型,本来应该是Object.prototype
console.log(typeof(B)); //object
console.log(B.__proto__ === A); //true
console.log(B.height); //168
console.log(B.name); //lili
console.log(B.hasOwnProperty('name')); //false
console.log(B.hasOwnProperty('height')); //true
console.log('********************comes C');
var C = {say : function(){console.log('hello')}};
C.__proto__ = B;
console.log(typeof(C)); //object
console.log(C.__proto__ === B); //true
- C的原型是B B的原型是A ,这就叫原型链。
- 当我们用obj.xxx访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,最后,如果还没有找到,就只能返回undefined。
- 所以目前有proto和prototype两个关键词了。
- proto总是指向原型,用字面量创建的对象的原型都是Object.prototype,而不是Object。
- 对象可以直接调用父类的属性,hasOwnProperty可以区分是继承来的属性还是自身的属性。
2.使用构造函数
2.1构造函数的原型链
//写一个构造函数
function Student(name) {
this.name = name;
this.hello = function () {
console.log('Hello, ' + this.name + '!');
}
};
//构造函数
console.log('*************************look at Student.__proto__');
console.log(typeof(Student)); //function
console.log(Student.__proto__ === Function.prototype); //true
console.log(Function.prototype.__proto__ === Object.prototype); //true
console.log(Student.__proto__.__proto__ === Object.prototype); //true
所以 从构造函数到Object的
原型链是这样的
某个函数->Functin.prototype->Object.prototype
Object.prototype这一层有一些方法比如hasOwnProperty isPrototypeOf toString
Function.prototype这一层有一些属性比如arguments length name
2.2函数独有的prototype属性
另外,函数会有个prototype属性,是函数独有的,Object也有prototype属性,因为Object的type也是function。
//只有函数和Object有prototype属性,Object是function
console.log(typeof(Object)); //function
console.log(Student.prototype);
console.log(Student.prototype.__proto__ === Object.prototype);//true
console.log(Student.prototype.constructor === Student); //true
prototype包含一个constructor和proto,而constructor指向他自己的对象,proto指向Object.prototype
因为constructor指向自己,所以能够访问到自己的各种方法,
constructor是构造对象中关键的一环
2.3实例与构造函数的原型链
//构造出来的对象
var zhangsan = new Student('张三');
zhangsan.name; //张三
zhangsan.hello(); //弹出hello张三
console.log('*************************look at zhangsan');
console.log(zhangsan);
console.log(typeof(zhangsan));//object
console.log(zhangsan instanceof Student); //true
console.log(zhangsan instanceof Student); //true
console.log(Student instanceof Object); //true
zhangsan除了有正常的name和hello以为还有一个proto
指向构造函数的prototype,
console.log('*************************look at zhangsan.__proto__');
console.log(zhangsan.__proto__ === Student.prototype);
console.log(Student.prototype.constructor.__proto__ === Function.prototype);
console.log(Student.prototype.constructor.__proto__.__proto__ === Object.prototype);
构造函数
3.Array Function Object关系
//函数的原型链
console.log('********************111111');
var f1 = function(){};
console.log(f1.__proto__ === Function.prototype); //true
console.log(Function.prototype.__proto__ === Object.prototype); //true
//数组的原型链
console.log('********************222222');
var arr = [1,2]
console.log(arr.__proto__ === Array.prototype); //true
console.log(Array.prototype.__proto__ === Object.prototype); //true
//类型
console.log('********************33333');
console.log(typeof(f1)); //function
console.log(typeof(Function)); //function
console.log(typeof(arr)); //object
console.log(typeof(Array)); //function
console.log(typeof(Object)); //function
image
最后再贴一张别人总结的混乱关系图
image