关于javascript:关于原型和原型链

38次阅读

共计 3895 个字符,预计需要花费 10 分钟才能阅读完成。

作为本人的笔记,不做过多解释:
首先须要先理解“构造函数”

function Person(name, gender){    // 申明一个构造函数
      this.name = name
      this.gender = gender
      this.say = function(){console.log(` 我是 ${name}, 是一个 ${gender}生...`);
      }
}
const personFun = new Person('张嘀嗒', '男')   
personFun.say()  //  我是张嘀嗒,是一个男生...

每个构造函数的实例对象 (personFun) 都能通过 constructor 来找到构造函数 (Person) 自身

console.log('通过 constructor 找到实例的构造函数',personFun.constructor === Person);//true

此时咱们能够应用函数对象的 prototype 属性来给构造函数预约义属性,prototype 能够了解为就是构造函数的原型对象

 function Car(){
      Car.prototype.name = '飞驰'
      Car.prototype.color = '红色'
      Car.prototype.say = function(){console.log(` 我的牌子是 ${this.name},色彩是 ${this.color}`);
      }
}
const carFun = new Car()
carFun.say()  // 我的牌子是飞驰,色彩是红色

咱们用更简洁直观的形式解说函数的 prototype 属性:

  • 原型对象就是一个一般对象,用法也是和一般对象一样
  • 构造函数的原型对象外面的办法是共有的办法,所有对应的 new 进去的实例对象都能调用原型对象外面的办法
  • prototype 外面保留着能够被实例共享的办法,此外外面还会有一个 constructor 的属性指向该原型对象的构造函数
    用法示例:
function Dog(){}
    Dog.prototype = {
      name: '旺财',
      color: '黑白灰',
      say(){console.log(` 原型对象:我的名字是 ${this.name}, 色彩是 ${this.color}`);
      }
}
const dogFun = new Dog()
dogFun.say()    // 原型对象:我的名字是旺财, 色彩是黑白灰
  • 在个别状况下,所有的原型对象 prototype 都有一个自带的 constructor 属性,

    • constructor 是一个指针,指向该 prototype 属性所在的函数 [Person, Car, Dog]
    • 也就是说 Person.prototype.constructor == Person
    • 此时,咱们能够看到在最下面构造函数那里,构造函数的实例对象也有 constructor 属性
    • 由此能够引申出 –> Person.prototype.constructor === personFun.constructor === Person
    • 对于为什么实例对象会间接有 constructor 属性,而且为什么和原型对象的指向是一样的,能够了解为在创立示例对象的时候执行了如下示例(帮忙了解,不能运行):
      —>const personFun = new Person()
      —>Person.prototype = personFun

js 在新建对象的时候(包含函数对象和一般对象),都会内置一个 proto 的内置属性用于指向 创立该对象的构造函数的原型对象,所以:

console.log('__proto__指向该对象的构造函数的原型对象', personFun.__proto__ === Person.prototype);  // true
console.log('__proto__指向该对象的构造函数的原型对象 2', personFun.__proto__.constructor === Person.prototype.constructor === Person);  // true

所以得出以下论断:

 * __proto__是什么?* 因为 personFun.__proto__ === personFun.prototype === Person
 * 所以 __proto__ 指向 构造函数的原型对象 prototype,可称为隐式原型
 * 
 * 一点区别:* 对象数据都有 __proto__属性指向该对象的构造函数的原型对象
 * 函数对象既有 __proto__ 指向该实例对象的革新函数的原型对象,还有 prototype 属性 (原型对象自身) 间接指向原型对象

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 构造函数
    function Person(name, gender){
      this.name = name
      this.gender = gender
      this.say = function(){console.log(` 我是 ${name}, 是一个 ${gender}生...`);
      }
    }
    const personFun = new Person('张嘀嗒', '男')   
    personFun.say()  //  我是张嘀嗒,是一个男生...
    // 每个构造函数的实例对象都能通过 constructor 来找到构造函数自身
    console.log('通过 constructor 找到实例的构造函数',personFun.constructor === Person);

    // 利用函数对象的 prototype 属性给构造函数预约义属性,prototype ---> 原型对象
    function Car(){
      Car.prototype.name = '飞驰'
      Car.prototype.color = '红色'
      Car.prototype.say = function(){console.log(` 我的牌子是 ${this.name},色彩是 ${this.color}`);
      }
    }
    const carFun = new Car()
    carFun.say()  // 我的牌子是飞驰,色彩是红色

    /**
     * 用更简洁直观的形式解说函数的 prototype 属性 ---> 原型对象就是一个一般对象,用法也是和一般对象一样
     * 构造函数的原型对象外面的办法是共有的办法,所有对应的 new 进去的实例对象都能调用原型对象外面的办法
     * prototype 外面保留着能够被实例共享的办法,此外外面还会有一个 constructor 的属性指向该原型对象的构造函数
     * */
    function Dog(){}
    Dog.prototype = {
      name: '旺财',
      color: '黑白灰',
      say(){console.log(` 原型对象:我的名字是 ${this.name}, 色彩是 ${this.color}`);
      }
    }
    const dogFun = new Dog()
    dogFun.say()    // 原型对象:我的名字是旺财, 色彩是黑白灰

    /**
     * 在个别状况下,所有的原型对象 prototype 都有一个自带的 constructor 属性,* constructor 是一个指针,指向该 prototype 属性所在的函数 [Person, Car, Dog]
     * 也就是说 Person.prototype.constructor == Person
     * 此时,咱们能够看到在最下面构造函数那里,构造函数的实例对象也有 constructor 属性
     * 由此能够引申出 --> Person.prototype.constructor === personFun.constructor === Person
     * 对于为什么实例对象会间接有 constructor 属性,而且为什么和原型对象的指向是一样的,能够了解为在创立示例对象的时候执行了如下示例(帮忙了解,不能运行):* --->const personFun = new Person()
     * --->Person.prototype = personFun
     * */

    //js 在新建对象的时候(包含函数对象和一般对象),都会内置一个 __proto__ 的内置属性用于指向 创立该对象的构造函数的原型对象,所以:console.log('__proto__指向该对象的构造函数的原型对象', personFun.__proto__ === Person.prototype);  // true
    console.log('__proto__指向该对象的构造函数的原型对象 2', personFun.__proto__.constructor === Person.prototype.constructor === Person);  // true
    
    /**
     * 所以得出以下论断:* __proto__是什么?* 因为 personFun.__proto__ === personFun.prototype === Person
     * 所以 __proto__ 指向 构造函数的原型对象 prototype,可称为隐式原型
     * 
     * 一点区别:* 对象数据都有 __proto__属性指向该对象的构造函数的原型对象
     * 函数对象既有 __proto__ 指向该实例对象的革新函数的原型对象,还有 prototype 属性 (原型对象自身) 间接指向原型对象
     * 
    */
    let num = Number.constructor === Function
    console.log(num);

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

正文完
 0