Skip to content
  • 创建对象的几种方法
  • 原型、构造函数、实例、原型链
  • instanceof 的原理
  • new 运算符

创建对象的几种方法

javascript
// 第一种方式:字面量
var o1 = { name: 'o1' }
var o2 = new Object({ name: 'o2' })

// 第二种方式:构造函数
var M = function (name) {
  this.name = name
}
var o3 = new M('o3')

// 第三种方式:Object.create
var p = { name: 'p' }
var o4 = Object.create(p)

console.log(o1) // { name: 'o1' }
console.log(o2) // { name: 'o2' }
console.log(o3) // M { name: 'o3' }
console.log(o4) // {}

原型、构造函数、实例、原型链

面试-原型链.png

对象是函数创建的,而函数却又是一种对象。也是属性的集合,可以对函数进行自定义属性。 每个函数都有一个属性叫做 prototype。 这个 prototype 的属性值是一个对象,默认的只有一个叫做 constructor 的属性,指向这个函数本身。

javascript
var Fn = function () {
  this.name = 'WuChenDi'
  this.old = 23
}
var f1 = new Fn()
console.log(f1) // Fn { name: 'WuChenDi', old: 23 }
console.log(Fn)
console.log(Fn.prototype)
console.log(f1.__proto__ === Fn.prototype) // true
console.log(Fn.prototype.constructor === Fn) // true

面试-原型链-原型与原型链.png

从上图可以看到对象的原型,指向构造函数的 prototype 属性。 f1.proto指向构造函数的 prototype 属性,就是对象的原型。所以 f1.proto === Fn.prototype 为 true prototype 的属性值是一个对象,默认的只有一个叫做 constructor 的属性,指向这个函数本身。 proto就是指向构造函数的 prototype 属性,Fn.prototype 就是对象的原型 即,每个由构造函数创建的对象都有一个proto属性,指向创建该对象的函数的 prototype。

md
var 对象名 = new 函数名()
对象名.**proto**=== 函数名.prototype

instanceof

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

面试-原型链-instanceof.png

javascript
// 第一种方式:字面量
var o1 = { name: 'o1' }
var o2 = new Object({ name: 'o2' })

// 第二种方式:构造函数
var M = function (name) {
  this.name = name
}
var o3 = new M('o3')

// 第三种方式:Object.create
var p = { name: 'p' }
var o4 = Object.create(p)

console.log(o3 instanceof M) // true
console.log(o3 instanceof Object) // true
console.log(o3.__proto__ === M.prototype) // true
console.log(M.prototype.__proto__ === Object.prototype) // true
console.log(o3.__proto__.constructor === M) // true

new 运算符

  • 一个新对象被创建。他继承自foo.prototype
  • 构造函数 foo 被执行。执行的时候,相应的传参会被传入,同时上下文 (this) 会被指定为这个新实例。 new foo 等同于 new foo(), 只能用在不传递如何参数的情况
  • 如果构造函数返回一个 "对象" ,那么这个对象会取代整个 new 出来的结果。如果构造函数没有返回对象,那么 new 出来的结果为步骤1创建的对象
javascript
// 第一种方式:字面量
var o1 = { name: 'o1' }
var o2 = new Object({ name: 'o2' })

// 第二种方式:构造函数
var M = function (name) {
  this.name = name
}
var o3 = new M('o3')

// 第三种方式:Object.create
var p = { name: 'p' }
var o4 = Object.create(p)

M.prototype.say = function () {
  console.log('say hi')
}

var o5 = new M('o5')

var new2 = function (func) {
  var o = Object.create(func.prototype)
  var k = func.call(o)
  if (typeof k === 'object') {
    return k
  } else {
    return o
  }
}

console.log((o6 = new2(M))) // M { name: undefined }
console.log(o6 instanceof M) // true
console.log(o6 instanceof Object) // true
console.log(o6.__proto__.constructor === M) // true

M.prototype.walk = function () {
  console.log('walk')
}

o6.walk() // walk
o3.walk() // walk

常问

JS 的 new 操作符做了哪些事情?

new 操作符新建了一个空对象,这个对象原型指向构造函数的 prototype,执行构造函数后返回这个对象。