浅显的概念

1.png
就是通过调用构造函数实例化出的对象的原型

prototype指向一块内存地址,然后这块内存地址存储的就是一个对象

constructor属性返回对象的构造函数
2.png

仅对构造函数有作用
3.png
4.png

proto

1.jpg
实例:

  1. var a = {};
  2. console.log(a.prototype); //undefined,印证prototype是函数才有的属性
  3. console.log(a.__proto__); //Object {}
  4. var b = function(){}
  5. console.log(b.prototype); //b {}
  6. console.log(b.__proto__); //function() {}

虽然proto并不是w3c的标准属性,但是原型的这条线在所有浏览器都存在的,而如果是chrome内核的浏览器或者是火狐和Safari是可以访问这个属性,这几个浏览器为方便我们学习或者调式而创造出来的隐秘属性

  1. <body>
  2. <script>
  3. function People(name, age, sex) {
  4. this.name = name;
  5. this.age = age;
  6. this.sex = sex;
  7. }
  8. // 实例化
  9. var xiaoming = new People('小明', 12, '男');
  10. // 测试三角关系是否存在
  11. console.log(xiaoming.__proto__ === People.prototype);
  12. </script>
  13. </body>

5.png
实例与构造函数是没有直接联系的,但是与原型对象有直接联系

  1. console.log(xiaoming.__proto__ === People.prototype) // true
  2. console.log(xiaoming.__proto__.constructor === People) // true

指向谁

2.jpg
实例:

  1. /*1、字面量方式*/
  2. var a = {};
  3. console.log(a.__proto__); //Object {}
  4. console.log(a.__proto__ === a.constructor.prototype); //true
  5. /*2、构造器方式*/
  6. var A = function(){};
  7. var a = new A();
  8. console.log(a.__proto__); //A {}
  9. console.log(a.__proto__ === a.constructor.prototype); //true
  10. /*3、Object.create()方式*/
  11. var a1 = {a:1}
  12. var a2 = Object.create(a1);
  13. console.log(a2.__proto__); //Object {a: 1}
  14. // (此处即为图1中的例外情况)
  15. console.log(a.__proto__ === a.constructor.prototype); //false

在prototype上添加方法

1.png
2.png


3.png
4.png
5.png

原型链

3.jpg
实例:

  1. var A = function(){};
  2. var a = new A();
  3. console.log(a.__proto__); // A {}(即构造器function A 的原型对象)
  4. console.log(a.__proto__.__proto__); // Object {}(即构造器function Object 的原型对象)
  5. console.log(a.__proto__.__proto__.__proto__); // null

原型链查找

6.png
7.png

我们通过代码来演示对象确实隐藏着该属性

  1. <body>
  2. <script>
  3. function People(name,age,sex) {
  4. this.name = name;
  5. this.age = age;
  6. this.sex = sex;
  7. }
  8. People.prototype.nationality = '中国';
  9. var xiaoming = new People('小明',12,'男');
  10. console.log(xiaoming.nationality);
  11. console.log(xiaoming);
  12. </script>
  13. </body>

8.png将其展开
9.png

遮蔽效应【可理解局部覆盖全局】

此时如果我们在new一个对象出来会是什么情形呢?
10.png
由于tom也是People的实例,所以他的原型也会指向prototype对象
12.png
Tom也是可以打点访问国籍属性的

而如果我们的Tom本身就有国籍属性,比如我们给它定义一个美国,这时他的国籍属性想想必然是美国,因为他本身就有了,所以浏览器自然就不会去查找原型上的属性了,这就是遮蔽效应,或者可以理解为这是一个局部变量把全局变量也就是原型的给覆盖掉了
13.png

  1. <body>
  2. <script>
  3. function People(name, age, sex) {
  4. this.name = name;
  5. this.age = age;
  6. this.sex = sex;
  7. }
  8. // 往原型上添加nationality属性
  9. People.prototype.nationality = '中国';
  10. // 实例化
  11. var xiaoming = new People('小明', 12, '男');
  12. var tom = new People('汤姆', 10, '男');
  13. tom.nationality = '美国';
  14. console.log(xiaoming.nationality); // 中国
  15. console.log(xiaoming);
  16. console.log(tom.nationality); // 美国
  17. 'nationality' in xiaoming // true
  18. </script>
  19. </body>

14.png

原型链的终点

Object可以看作是所有对象的构造函数,在js万物基于Object,一切从它派生而来,是祖先
6.png

数组的原型链

7.png

从object继承而来(相关性)

hasOwnProperty【检查对象是否真正自己拥有某属性或方法】

沿用上例
16.png

in运算符

沿上
17.png