美文网首页深入JavaScript
深入JavaScript Day09 - 隐式原型、显示原型、n

深入JavaScript Day09 - 隐式原型、显示原型、n

作者: 望穿秋水小作坊 | 来源:发表于2022-01-15 18:52 被阅读0次

一、理解原型、原型链的一些要点【最重要的概念梳理,一定要理解】

1、对函数 function Foo(){} 调用new会发生以下五件事

①创建一个新的空对象
②将新对象的proto属性指向函数的Prototype对象
③将this指针指向新的对象(new 绑定)
④指向函数体代码
⑤如果函数没有明确返回值,则返回新对象

2、关于Object的内容

①Object.prototype.proto === null
②let o = {a:10};是一种语法糖,完整代码是: let o = new Object({a:10});
③因此:o.proto === Object.prototype; o.proto.proto === Object.prototype.proto === null;

3、关于 proto、prototype、constructor 之间关系理解

proto 凡是对象都有的属性,基本上JavaScript中所有的对象最终都指向 Object.prototype;
② prototype 是函数才拥有的属性,执行代码 let o = new Foo(),会将o.proto指向Foo.prototype;
③ 所有的 prototype 都有一个constructor属性,constructor指向函数对象本身,Foo === o.proto.constructor === o.constructor === Foo.prototype.constructor

4、关于Foo和Function之间的关系的理解

function Foo() {} 是语法糖 const Foo = new Funciton("xxx");因此 Foo.proto === Function.prototype

二、JavaScript创建对象的方式

1、如下创建对象的方式,如果创建100个对象,有什么问题吗?

var p1 = {
  name: "张三",
  age: 18,
  height: 1.88,
  eat: function () {
    console.log(this.name + "在吃饭~");
  },
};

var p2 = {
  name: "张三",
  age: 17,
  height: 1.77,
  eat: function () {
    console.log(this.name + "在吃饭~");
  },
};

console.log(p1);
console.log(p2);

console.log(p1.eat === p2.eat);

  • 【问题一】100个对象,就有100份这样对象定义的代码,代码非常冗余;
  • 【问题二】100个对象的eat方法,都是不同方法,其实代码执行体是完全一致的,没必要创建100方法对象;
  • 【问题三】没有类型提示,所有类型都是Object,太笼统了。

2、通过工厂模式创建对象

function eat() {
  console.log(this.name + "在吃饭~");
}

function createPersonFoactory(name, age, height) {
  return {
    name,
    age,
    height,
    eat,
  };
}

var p1 = createPersonFoactory("张三", 18, 1.88);
var p2 = createPersonFoactory("李四", 17, 1.77);

console.log(p1);
console.log(p2);

console.log(p1.eat === p2.eat);

p1.eat();
p2.eat();

  • 【优点】解决代码冗余和函数重复定义的问题
  • 【缺点】依然没有类型的概念

3、借助构造函数创建对象的方案

image.png

三、构造函数、new、对象的原型

1、构造函数在什么时候自动调用?JavaScript中的构造函数和其他语言有什么不同?

  • 【调用】构造函数在对象创建的时候,自动调用。
  • 【在其他语言中】构造器是类中的一个方法
  • 【在JavaScript中】构造函数只是一个普通的函数,如果这么一个普通的函数被使用new关键字调用,那么它就被称之为构造函数
image.png

2、如果一个函数被使用new操作符调用了,那么它会执行如下操作?

  • ①在内存中创建一个新的对象(空对象);
  • ②这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性;
  • ③构造函数内部的this,会指向创建出来的新对象;(new 绑定);
  • ④执行函数的内部代码(函数体代码);
  • ⑤如果构造函数没有返回非空对象,则返回创建出来的新对象;
image.png

3、认识对象的原型。是所有对象都有原型吗?怎么获取?隐式原型

  • 只要是对象都会有这样的一个内置属性[[prototype]]
  • 通过【proto】 或者【Object.getPrototypeOf】可以获取到
image.png

4、认识函数的原型 prototype。所有函数都有都有prototype吗?显示原型

image.png

5、理解new操作时,对象的隐式原型指向显示原型的过程?

image.png image.png image.png

5、理解constructor属性,这个属性存在于哪里,指向谁?

  • 默认情况下显示原型都会添加一个属性叫做constructor,这个constructor指向当前的函数对象
image.png

6、重写显示原型的方式?

image.png image.png

7、如何查看一个属性的属性描述符?

function Person(name) {
  this.name = name;
}
var p1 = new Person("zhansan");
var p2 = new Person("lisi");

console.log(p1.__proto__);
console.log(Object.getOwnPropertyDescriptors(p1));
console.log(Object.getOwnPropertyDescriptors(p1.__proto__));
image.png

相关文章

网友评论

    本文标题:深入JavaScript Day09 - 隐式原型、显示原型、n

    本文链接:https://www.haomeiwen.com/subject/fgkthrtx.html