JS-原型与原型链

目录

1. 原型(prototype)

2.显式原型与隐式原型

3.原型链

4.相关问题


 

1. 原型(prototype)

每一个函数都会创建一个prototype属性(指向原型对象),这个属性是一个对象(默认是一个空的实例对象,没有自己设置的方法和属性),包含其引用类型的实例共享的方法和属性(原型对象的优点),所有原型对象都包含一个constructor属性(指回这个函数)。

// 构造函数声明可以是函数表达式和函数声明(存在函数提升)
        // function Person() {

        // }
        // let Person = function() {

        // }
        function Person() {

        }
        console.log(typeof Person.prototype);
        // 默认指向一个Object空对象(没有我们的属性)
        console.log(Person.prototype);
        // 原型对象中有一个属性constructor, 它指向函数对象
        console.log(Person.prototype.constructor === Person);
        //给原型对象添加属性(一般是方法) ===>实例对象可以访问
        Person.prototype.singSong = function() {
            console.log('song')
        }
        let p = new Person
        p.singSong()

 

 

2.显式原型与隐式原型

1. 每个函数function都有一个prototype,即显式原型(属性),默认值是一个空对象,在定义函数时自动添加的

2. 每个实例对象都有一个__proto__,可称为隐式原型(属性),默认值是其构造函数的prototype值,创建对象时自动添加的

3. 对象的隐式原型的值为其对应构造函数的显式原型的值

 

 function Person() {

        }
        // 默认指向一个Object空对象(没有我们的属性)
        console.log(Person.prototype);
        // 原型对象中有一个属性constructor, 它指向函数对象
        console.log(Person.prototype.constructor === Person);//true
        // 每个实例对象都有一个__proto__
        let p = new Person()  // 内部语句: this.__proto__ = Fn.prototype
        console.log(p.__proto__); 
        // 对象的隐式原型的值为其对应构造函数的显式原型的值
        console.log(p.__proto__ === Person.prototype);//true
        // 正常的原型链都会终止于Object原型对象,而Object原型的原型是null
        console.log(Person.prototype.__proto__ === Object.prototype);//true
        console.log(Person.prototype.__proto__.constructor === Object); //true
        console.log(Person.prototype.__proto__.__proto__ === null);//true

注意:原型对象,构造函数和实例是三个不同的对象。实例通过隐式原型链接到原型对象,但实际上指向藏特性[[Prototype]] 。

3.原型链

在访问一个对象的属性时,

    * 先在自身属性中查找,找到返回

    * 如果没有, 再沿着__proto__这条链向上查找, 找到返回

    * 如果最终没找到, 返回undefined

  * 别名: 隐式原型链

  * 作用: 查找对象的属性(方法)

 

 console.log(Object)
  console.log(Object.prototype)
  console.log(Object.prototype.__proto__)
  function Fn() {
    this.test1 = function () {
      console.log('test1()')
    }
  }
  console.log(Fn.prototype)
  Fn.prototype.test2 = function () {
    console.log('test2()')
  }

  var fn = new Fn()

  fn.test1()
  fn.test2()
  console.log(fn.toString())
  console.log(fn.test3)//原型链查找方式:如果最终没找到, 返回undefined
  // fn.test3() Uncaught TypeError: fn.test3 is not a function


  /*
  1. 函数的显示原型指向的对象默认是空Object实例对象(但Object函数不满足)
   */
  console.log(Fn.prototype instanceof Object) // true
  console.log(Object.prototype instanceof Object) // false
  console.log(Function.prototype instanceof Object) // true
  /*
  2. 所有函数都是Function的实例(包含Function)
  */
  console.log(Function.__proto__===Function.prototype)
  /*
  3. Object的原型对象是原型链尽头
   */
  console.log(Object.prototype.__proto__) // null

 注意:Object.prototype并不是Object的实例对象

 图解:

4.相关问题

 注意点:

1. 读取对象的属性值时: 会自动到原型链中查找

2. 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值

3. 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上

instanceof理解Object与Function之间的关系: (互为对方的实例,且自己是自己的实例)

  console.log(Object instanceof Function) // true
  console.log(Object instanceof Object) // true
  console.log(Function instanceof Function) // true
  console.log(Function instanceof Object) // true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值