JavaScript - 原型和原型链

  • 1. 创建对象

所有的对象都是通过new 函数()创建的,该函数叫做构造函数

  1. 函数可以产生对象
function test() {
    this.name = "车车";
}
let obj = new test() //test {name: "车车"}
  1. 所有对象都是靠函数产生的
let obj={age:18};  //对象字面量的方式
//相当于
let obj = new Object();
obj.age = 18

函数也是一个对象,它是通过new Function创建的

function test() {}
console.log(test.name); //test
console.log(test.length); //0
function add(a, b) {
    return a + b;
}
//相当于
var add = new Function("a", "b", "return a+b");
console.log(add(2, 3));  //5

小结:
(1)函数是通过new Function创建的:
函数是通过new Function创建的
(2)普通对象是通过new 函数创建的
普通对象是通过new 函数创建的

  • 2. 构造函数为什么能通过new 关键字创建对象

  1. new 时发生的三步
  • 创建一个新对象,并继承其构造函数的prototype,这一步是为了继承构造函数原型上的属性和方法
  • 执行构造函数,方法内的this被指定为该新实例,这一步是为了执行构造函数内的赋值操作;
  • 返回新实例(规范规定,如果构造方法返回了一个对象,那么返回该对象,否则返回第一步创建的新对象)
  1. 用函数模拟实现new
function myNew(foo,...args){
    // 相当于obj.__proto__ = Foo.prototype
    let obj = Object.create(foo.prototype)
    // 执行构造方法, 并为其绑定新this
    let result = foo.apply(obj,args)
    // 如果构造方法已经return了一个对象, 那么就返回该对象, 一般情况下,构造方法不会返回新实例,但使用者可以选择返回新实例来覆盖new创建的对象 否则返回myNew创建的新对象
    return typeof result == 'object' && result != null ? result :obj
}

function Foo(name) {
    this.name = name
}
const newObj = myNew(Foo,'cc')
console.log(newObj)  // Foo {name: "cc"}
console.log(newObj instanceof Foo)   // true
  • 3. 原型

  1. 所有的函数都有原型属性prototype
  2. 默认情况下,prototype是一个Object对象
    prototype原型对象中constructor属性指向构造函数本身
 function test(){} 
 console.log(test === test.prototype.constructor)  //true
 console.log(test.prototype === test.prototype.constructor.prototype)  //true

原型的constructor指向构造函数本身

  • 4. 隐式原型

  1. 所有的对象都有隐式原型__proto__属性
  2. 隐式原型是一个对象,指向创建该对象的构造函数的原型prototype
function test() {}
var t1 = new test();
var t2 = new test();
console.log(t1._proto_ === t2._proto_)   //true
  1. 在查找对象成员时,若对象本身没有该成员,则会到隐式原型中查找
function test() {}
test.prototype.name = '车车'

var t1 = new test();
var t2 = new test();

t1.name ;  //"车车"
t1.name === t2.name  //true

t1.constructor  //function test() {}
//构造出来的实例对象t1上也有属性constructor并且指向构造实例t1的构造函数test,这个属性是从构造函数原型对象中找到的

小结:

  • 所有函数的隐式原型,都指向Function的原型
  • 所有的函数原型的隐式原型,都指向Object的原型
    链条的全貌:
    在这里插入图片描述
  • 5. 原型链

  • 由于原型prototype本身是对象,因此,它也有隐式原型,指向的规则不变;这样一来,从某个对象出发,依次寻找隐式原型的指向,将形成一个链条,该链条叫做原型链。

  • 在查找对象成员时,若对象本身没有该成员,则会到原型链中查找

  • 特殊的两个情况:

    1. Function的隐式原型指向自己的原型
    2. Object原型的隐式原型指向null
  • 总结:

  1. 自定义函数和Object都是new Function得到
  2. 所有的属性都会沿着原型链寻找,最终会一直找到Object.prototype停止
     Object.prototype._proto_ = null
     Function.prototype === Function.__proto_
     Function..prototype._proto_ === Object.prototype
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值