原型(prototype属性)和原型链。 重要!!!

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <title>01_原型(prototype)</title>
 6 </head>
 7 <body>
 8 <!--
 9 1. 函数的prototype属性(图)
10   * 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)
11   * 原型对象中有一个属性constructor, 它指向函数对象
12 2. 给原型对象添加属性(一般都是方法)
13   * 作用: 函数的所有实例对象自动拥有原型中的属性(方法)
14 -->
15 <script type="text/javascript">
16 
17   // 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)
18   console.log(Date.prototype, typeof Date.prototype) //object
19   function Fun () {//alt + shift +r(重命名rename)
20 
21   }
22   console.log(Fun.prototype)  // 默认指向一个Object空对象(没有我们的属性)
23 
24   // 原型对象中有一个属性constructor, 它指向函数对象
25   console.log(Date.prototype.constructor===Date) //true
26   console.log(Fun.prototype.constructor===Fun) //true
27 
28   //给原型对象添加属性(一般是方法) ===>实例对象可以访问
29   Fun.prototype.test = function () {
30     console.log('test()')
31   }
32   var fun = new Fun()
33   fun.test()  //test()
34 
35 
36 
37 
38 
39 </script>
40 </body>
41 </html>

 

显式原型与隐式原型
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>02_显式原型与隐式原型</title>
</head>
<body>
<!--
1. 每个函数function都有一个prototype,即显式原型(属性)
2. 每个实例对象都有一个__proto__,可称为隐式原型(属性)
3. 对象的隐式原型的值为其对应构造函数的显式原型的值
4. 内存结构(图)
5. 总结:
  * 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象
  * 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
  * 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)
-->
<script type="text/javascript">
  //定义构造函数
  function Fn() {   // 内部语句: this.prototype = {}

  }
  // 1. 每个函数function都有一个prototype,即显式原型属性, 默认指向一个空的Object对象
  console.log(Fn.prototype)
  // 2. 每个实例对象都有一个__proto__,可称为隐式原型
  //创建实例对象
  var fn = new Fn()  // 内部语句: this.__proto__ = Fn.prototype
  console.log(fn.__proto__)
  // 3. 对象的隐式原型的值为其对应构造函数的显式原型的值
  console.log(Fn.prototype===fn.__proto__) // true
  //给原型添加方法
  Fn.prototype.test = function () {
    console.log('test()')
  }
  //通过实例调用原型的方法
  fn.test()



</script>
</body>
</html>

 

每个函数function都有一个prototype,即显式原型(属性)
2. 每个实例对象都有一个__proto__,可称为隐式原型(属性)
3. 对象的隐式原型的值为其对应构造函数的显式原型的值
4. 内存结构(图)
5. 总结:
  * 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象
  * 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
  * 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)
 
 

 

 原型链

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <title>03_原型链</title>
 6 </head>
 7 <body>
 8 <!--
 9 1. 原型链(图解)
10   * 访问一个对象的属性时,
11     * 先在自身属性中查找,找到返回
12     * 如果没有, 再沿着__proto__这条链向上查找, 找到返回
13     * 如果最终没找到, 返回undefined
14   * 别名: 隐式原型链
15   * 作用: 查找对象的属性(方法)
16 2. 构造函数/原型/实体对象的关系(图解)
17 3. 构造函数/原型/实体对象的关系2(图解)
18 -->
19 <script type="text/javascript">
20   console.log(Object)  //ƒ Object() { [native code] }  Object函数类型
21   console.log(Object.prototype)  //Object   Object函数的prototype属性对应了一个Object原型对象
22   console.log(Object.prototype.__proto__) //null  object原型对象没有__proto__,他就是原型对象的尽头
23   function Fn() {
24     this.test1 = function () {
25       console.log('test1()')
26     }
27   }
28   console.log(Fn.prototype)
29   Fn.prototype.test2 = function () {
30     console.log('test2()')
31   }
32 
33   var fn = new Fn()
34 
35   fn.test1()
36   fn.test2()
37   console.log(fn.toString())
38   console.log(fn.test3)  // undefined
39   // fn.test3()  //TypeError: fn.test3 is not a function
40 
41 
42   /*
43   1. 函数的显示原型指向的对象默认是空Object实例对象(但Object不满足)
44    */
45   console.log(Fn.prototype instanceof Object) // true
46   console.log(Object.prototype instanceof Object) // false
47   console.log(Function.prototype instanceof Object) // true
48   /*
49   2. 所有函数都是Function的实例(包含Function)
50   */
51   console.log(Function.__proto__===Function.prototype)
52   /*
53   3. Object的原型对象是原型链尽头
54    */
55   console.log(Object.prototype.__proto__) // null
56 
57 </script>
58 </body>
59 </html>

 

 

原型链(图解)
  * 访问一个对象的属性时,
    * 先在自身属性中查找,找到返回
    * 如果没有, 再沿着__proto__这条链向上查找, 找到返回
    * 如果最终没找到, 返回undefined
  * 别名: 隐式原型链
  * 作用: 查找对象的属性(方法)
2. 构造函数/原型/实体对象的关系(图解)
3. 构造函数/原型/实体对象的关系2(图解)
 
 
面试题
 
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <title>06_面试题</title>
 6 </head>
 7 <body>
 8 
 9 <script type="text/javascript">
10   /*
11   测试题1
12    */
13   function A () {
14 
15   }
16   A.prototype.n = 1
17 
18   var b = new A()
19 
20   A.prototype = {
21     n: 2,
22     m: 3
23   }
24 
25   var c = new A()
26   console.log(b.n, b.m, c.n, c.m)//1 undinded  2  3
27 
28 
29   /*
30    测试题2
31    */
32   function F (){}
33   Object.prototype.a = function(){
34     console.log('a()')
35   }
36   Function.prototype.b = function(){
37     console.log('b()')
38   }
39   
40   var f = new F()
41   f.a()  // a()
42   f.b()  //报错
43   F.a()  // a()
44   F.b()  //b()
45   console.log(f)
46   console.log(Object.prototype)
47   console.log(Function.prototype)
48 
49 </script>
50 </body>
51 </html>

 

面试题1

 

面试题2

 

 

 

总结:1.每个自定义函数的原型对象是函数obj的实例化对象,每个自定义函数的原型对象的--proto--隐士属性指向函数obj的原型对象, 而OBJ的原型的--proto-- 是null

 2.每个自定义函数是FUN的实例化对象

3.FUN自己new自己,他的显示和隐士原型属性指向的是他的原型对象

 

 

 ES5:寄生组合式继承:通过借用构造函数来继承属性和原型链来实现子继承父

    function ParentClass(name) {
      this.name = name;
    }
    ParentClass.prototype.sayHello = function () {
      console.log("I'm parent!" + this.name);
    }
    function SubClass(name, age) {
      //若是要多个参数可以用apply 结合 ,解构
      ParentClass.call(this, name);
      this.age = age;
    }
    SubClass.prototype = Object.create(ParentClass.prototype);
    SubClass.prototype.constructor = SubClass;
    SubClass.prototype.sayChildHello = function (name) {
      console.log("I'm child " + this.name)
    }

    let testA = new SubClass('CRPER')


 

ES6语法: 其实就是ES5的语法糖,不过可读性很强..

    class ParentClass {
      constructor(name) {
        this.name = name;
      }
      sayHello() {
        console.log("I'm parent!" + this.name);
      }
    }

    class SubClass extends ParentClass {
      constructor(name) {
        super(name);
      }
      sayChildHello() {
        console.log("I'm child " + this.name)
      }
      // 重新声明父类同名方法会覆写,ES5的话就是直接操作自己的原型链上
      sayHello(){
        console.log("override parent method !,I'm sayHello Method")
      }
    }

    let testA = new SubClass('CRPER')

 

 

posted @ 2020-04-25 16:38  全情海洋  阅读(673)  评论(0编辑  收藏  举报