对象、原型、原型链

253 阅读1分钟

目录:

  1. 创建对象
  2. new Dog做了哪些事
  3. 重新认识函数
  4. ES6写法-class
  5. instanceof
  6. 原型链
  7. Object.create

一、创建对象

字面量方式创建

缺点:每创建一个对象,要写一次代码

let person = {  name: 'hunger', 
 sayName: function() {  
  console.log(`我的名字是${this.name}`) 
 } 
} 
people.sayName() 

let dog = { 
 color: 'yellow',  
sayColor() {    
console.log(`汪汪${this.color}`) 
 } 
}
 dog.sayColor()

构造函数方式创建

function Dog(color) {
  this.color = color 
 this.sayColor = function() {  
  console.log(`汪汪${this.color}`)
  } 
} 

let dog1 = new Dog('red') 
dog1.sayColor()
 
let dog2 = new Dog('yellow') 
dog2.sayColor(

二、new Dog做了哪些事

  1. 创建一个空对象 {},假设名字是 tmpObj
  2. 执行 Dog 函数,执行过程中对 this 操作就是对 tmpObj 进行操作
  3. 函数执行完后返回刚刚创建的 tmpObj
  4. 把 tmpObj 赋值给 dog1 (dog1也指向同一个对象)

问题

存在的问题

如果要创建10000个对象,每个对象内都用sayColor方 法,并且代码完全一样。能否复用?

三、重新认识函数

  1. 所有函数都有一个.prototype属性,对应的是一个空对象(暂且认为)
  2. 当用new 函数 创建对象时,对象都拥有.__proto__属性,都指向该函数 的.prototype
  3. 当使用对象的属性时,先从自有属性找,找不到再从.__proto__里找

优化

把方法放函数的prototype里

function Dog(color) { 
 this.color = color 
} 

Dog.prototype.sayColor = function() { 
 console.log(this.color) 
} 

let dog1 = new Dog('red') 
dog1.sayColor() 

let dog2 = new Dog('yellow') 
dog2.sayColor()

四、ES6写法-class

class是语法糖(语法糖,底层是一样的 只是换了个写法)

class Dog {  
constructor(color) {   
 this.color = color 
 } 

sayColor() { 
   console.log(`汪汪${this.color}`) 
 } 

 name = 'dog' 
}
let dog1 = new Dog('red')
 dog1.sayColor()

五、instanceof

用于检测构造函数的 prototype 属性是否出现在某个 实例对象的原型链上

class Dog {}

 let dog1 = new Dog() 
dog1 instanceof Dog   // true 

[] instanceof Array                  // true 
{} instanceof Object                 //true 
(function(){}) instanceof Function   //true 
Object instanceof Function           // true
  • 数组是Array函数的实例
  • 字面量对象是Object函数的实例
  • 函数是Function函数的实例
  • Object函数是Function函数的实例

几条经验

  1. new 一个函数,这个函数的 prototype等于创建的对象的 proto
  2. 普通的对象是Object函数创建的
  3. 任何函数都是由Function函数创建的
  4. Function创建了Function

六、原型链

对于如下代码,dog1.toString是哪里来 的?

class Dog { 
 constructor(color) {   
 this.color = color 
 } 
} 

let dog1  = new Dog('yellow') 
console.log(dog1.toString())    //"[object Object]" 
  1. new Dog创建dog1对象,Dog.prototype === dog1.proto
  2. dog1.__proto__是个普通对象,是由new Object 创建的,
  3. Object.prototype === dog1.proto.proto
  4. dog1.toString === dog1.proto.proto.toString

七、Object.create

创建一个新对象,用参数作为新对象 的原型__proto__

let person1 = {name: '饥人谷'} 
let person2 = Object.create(person1)  //  person2 简单的继承person1 
console.log(person2)
console.log(person.__proto__) 
console.log(person.name)