- 创建对象的几种方法
- 原型、构造函数、实例、原型链
- 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) // {}
原型、构造函数、实例、原型链
对象是函数创建的,而函数却又是一种对象。也是属性的集合,可以对函数进行自定义属性。 每个函数都有一个属性叫做 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
从上图可以看到对象的原型,指向构造函数的 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 属性是否出现在某个实例对象的原型链上。
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,执行构造函数后返回这个对象。