浅显的概念
就是通过调用构造函数实例化出的对象的原型
prototype指向一块内存地址,然后这块内存地址存储的就是一个对象
constructor属性返回对象的构造函数
proto
实例:
var a = {};
console.log(a.prototype); //undefined,印证prototype是函数才有的属性
console.log(a.__proto__); //Object {}
var b = function(){}
console.log(b.prototype); //b {}
console.log(b.__proto__); //function() {}
虽然proto并不是w3c的标准属性,但是原型的这条线在所有浏览器都存在的,而如果是chrome内核的浏览器或者是火狐和Safari是可以访问这个属性,这几个浏览器为方便我们学习或者调式而创造出来的隐秘属性
<body>
<script>
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 实例化
var xiaoming = new People('小明', 12, '男');
// 测试三角关系是否存在
console.log(xiaoming.__proto__ === People.prototype);
</script>
</body>
实例与构造函数是没有直接联系的,但是与原型对象有直接联系
console.log(xiaoming.__proto__ === People.prototype) // true
console.log(xiaoming.__proto__.constructor === People) // true
指向谁
实例:
/*1、字面量方式*/
var a = {};
console.log(a.__proto__); //Object {}
console.log(a.__proto__ === a.constructor.prototype); //true
/*2、构造器方式*/
var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}
console.log(a.__proto__ === a.constructor.prototype); //true
/*3、Object.create()方式*/
var a1 = {a:1}
var a2 = Object.create(a1);
console.log(a2.__proto__); //Object {a: 1}
// (此处即为图1中的例外情况)
console.log(a.__proto__ === a.constructor.prototype); //false
在prototype上添加方法
原型链
实例:
var A = function(){};
var a = new A();
console.log(a.__proto__); // A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); // Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); // null
原型链查找
我们通过代码来演示对象确实隐藏着该属性
<body>
<script>
function People(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
People.prototype.nationality = '中国';
var xiaoming = new People('小明',12,'男');
console.log(xiaoming.nationality);
console.log(xiaoming);
</script>
</body>
将其展开
遮蔽效应【可理解局部覆盖全局】
此时如果我们在new一个对象出来会是什么情形呢?
由于tom也是People的实例,所以他的原型也会指向prototype对象
Tom也是可以打点访问国籍属性的
而如果我们的Tom本身就有国籍属性,比如我们给它定义一个美国,这时他的国籍属性想想必然是美国,因为他本身就有了,所以浏览器自然就不会去查找原型上的属性了,这就是遮蔽效应,或者可以理解为这是一个局部变量把全局变量也就是原型的给覆盖掉了
<body>
<script>
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 往原型上添加nationality属性
People.prototype.nationality = '中国';
// 实例化
var xiaoming = new People('小明', 12, '男');
var tom = new People('汤姆', 10, '男');
tom.nationality = '美国';
console.log(xiaoming.nationality); // 中国
console.log(xiaoming);
console.log(tom.nationality); // 美国
'nationality' in xiaoming // true
</script>
</body>
原型链的终点
Object可以看作是所有对象的构造函数,在js万物基于Object,一切从它派生而来,是祖先
数组的原型链
从object继承而来(相关性)
hasOwnProperty【检查对象是否真正自己拥有某属性或方法】
沿用上例
in运算符
沿上