• 原型(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')
  • 相关阅读:
    java中使用静态字段和构造函数跟踪某个类所创建对象的个数
    java中静态初始化块的执行顺序
    Java字段初始化的规律
    java web第一次课堂测试1
    java课极限测试
    对于java中反编译命令的使用以及Integer包装类的查看
    在java的静态方法中访问类的实例成员
    [Android开发] 获取Android的Google Map API密钥
    [Android开发] 整合不同版本的android project的方法
    比特,字节和像素之间的关系
  • 原文地址:https://www.cnblogs.com/fsg6/p/12773775.html
Copyright © 2020-2023  润新知