对象
什么是对象
- 在JavaScript中,一切皆对象
如何创建一个对象
字面量形式
var obj = {}
构造函数(普通函数的写法,一般用首字母大写开头,用于区分构造函数和普通函数)(内部关键字this关键词)(关键字 new实例化一个对象)
// 构造函数
function Person(name){
this.name = name
this.say = ()=>{
console.log('I am ' + this.name);
}
}
// 通过new关键字实例化一个对象
const person1 = new Person('wu')
console.log(person1.name); //wu
person1.say()//I am wu
使用构造函数注意
- new 一个对象的过程 let man = new Person()
- 首先创建一个新的对象 var obj = {}
- 接着将空对象的__proto__指向构造函数的原型对象prototype
obj.__proto__= Person.prototype - 再接着将this指向空对象 Person.call(obj)
- 执行构造函数内部代码
- 最后将新对象返回
- 使用构造函数的时候,更推荐在构造函数内部定义属性,在原型上定义方法
// 构造器及其属性定义
function Test(a,b,c,d) {
// 属性定义
};
// 定义第一个方法
Test.prototype.x = function () { ... }
// 定义第二个方法
Test.prototype.y = function () { ... }
// 等等……
Object()构造函数
let stu1 = new Object()
stu1.name = 'hu'
stu1['age'] = 18
stu1.say = function(){console.log(this.name);}
let stu2 = new Object({
name:'wei',
say:function(){console.log(this.name);}
})
Object.create()
- 接受一个对象,为空报错
- 以某一个对象为原型对象,实例化一个新的对象出来
- 下边的例子say的方法(包括属性)是挂载在stu3的原型stu1上的(关于对象原型的后边会有讲解)
let stu3 = Object.create(stu1)
console.log(stu3);//{}
stu3.say() // hu
比较
通过 new 的方式创建对象和通过字面量创建有什么区别?
对于对象来说,其实都是通过new产生的。 更推荐字面量方式(无论是性能上还是可读性上) 通过new Object()方式 需要通过作用域链一层层找到Object,但是字面量方式不需要
面向对象的三大特征
- 封装:将公共的属性和方法(行为)封装在一个对象中
- 继承:子类可以继承父类的属性和方法
- 多态:同一个方法具有不同的表现形式
原型对象与原型链
单次翻译
prototype -> 原型
官方定义
- 原型对象:JavaScript 常被描述为一种基于原型的语言 (prototype-based language) ——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。
- 原型链 (prototype chain) :原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain) ,它解释了为何一个对象会拥有定义在其他对象中的属性和方法。
理解
- 对象的原型(可以通过
Object.getPrototypeOf(obj)或者已被弃用的__proto__属性获得)与构造函数的prototype属性之间的区别是很重要的。 - 前者是每个实例上都有的属性,后者是构造函数的属性。
- 也就是说,
Object.getPrototypeOf(new Foobar())和Foobar.prototype指向着同一个对象。 - 总而言之就是,每一个对象都有
__proto__属性,每一个函数都有prototype属性,然后实例化对象的__proto__指向他的构造函数的prototype属性(也就是原型对象)
原型链
原型链的顶端是null