创建对象的几种方式
- 对象字面量
var Person = {
name: 'tianzhen',
say: function() {
console.log(this.name)
}
}
Person.say()
- new Object()
var Person = new Object()
Person.name = 'tianzhen'
Person.say = function() {
console.log(this.name)
}
Person.say()
方法1和方法2都属于同一种方法,1是2的语法糖,可以看到,对象其实也是new出来的
- 使用原型
var Person = function() {}
Person.prototype.name = 'tianzhen'
Person.prototype.say = function() {
console.log(this.name)
}
var p = new Person()
p.say()
var p2 = new Person()
p2.say()
p和p2都可以共享原型上的属性和方法
原型到底是什么?
上面出现了prototype,那么它是函数的原型吗?
理解原型
当一个JavaScript对象在创建的时候,就会与之关联另一个对象(创建这个对象的函数的prototype),这个对象就是我们所说的原型,每一个对象都会从原型上继承属性
当一个函数在创建之后,就会产生一个原型对象(prototype),当通过这个函数的构造函数创建了一个具体对象后,这个具体对象中有一个属性(proto)指向原型
我们使用如下代码来分析原型是什么
function Person() {}
const p = new Person()
new 函数
我们通常称为是构造函数,它返回的是一个对象。
对象p的原型是什么?答案就是Person.prototype
那么Person的原型又是什么?
prototype
- 每一个函数都有一个prototype属性
- 它指向了一个对象
- 这个对象就是调用它的构造函数而创建的实例的原型
所以p的原型就是Person.prototype
__proto__
每一个对象(null除外)都有一个__proto__
属性,又称隐式原型,规范中定义为[[prototype]]
,它指向该对象的原型
- 根据上面的描述得出
- p有一个属性
p.__proto__
p.__proto__
指向p的原型即Person.prototype
- 那
Person
是个函数,它有没有__proto__
?
Person
是函数但也是对象,所以它也有__proto__
Person.__proto__ === ?
- 定义函数的另一种方式
new Function
const Person = new Function()
看到这里大家应该就明白了上面Person
的原型是什么了-- Person.__proto__
=== Function.prototype
那__proto__
又是从哪里来的?
- 来自Object.prototype
- 因为所有的原型都继承了Object.prototype,所以可以访问__proto__
- 访问
p.__proto__
可以理解为Object.getPrototypeOf(p)
总结
所以我们平时所说的原型其实就是对象的__proto__
,对象构造函数的prototype