对象
关于理解对象这个概念,我觉得这篇文章讲的好好 浅析面向过程与面向对象
其中介绍了什么是对象,面向过程和面向对象的区别是什么
如何创建对象
1.工厂模式
function createPerson(name,age,job){
var o = new Object()
o.name = name
o.age = age
o.job = job
}
var person = createPerson('joker','15','歌手')
缺点:无法知道创建出的对象的类型
2.构造函数
目前js有一些原生构造函数Object Array来创建对象,也可以自定义构造函数
function Person(name,age,job){
this.name = name
this.age = age
this.job = job
this.sayName = function(){
console.log(this.name)
}
}
var person = new Person('joker','15','歌手')
使用new操作符创建对象,会经过以下几个步骤(高级程序设计)
- 创建一个新对象
- 将构造函数的作用域赋值给新对象(因此this指向了这个新对象)
- 指向构造函数中的代码(给新对象添加属性)
- 返回新对象
代码大概这样
// ES5构造函数
let Parent = function (name, age) {
//1.创建一个新对象,赋予this,这一步是隐性的,
// let this = {};
//2.给this指向的对象赋予构造属性
this.name = name;
this.age = age;
//3.如果没有手动返回对象,则默认返回this指向的这个对象,也是隐性的
// return this;
};
const child = new Parent();
winter 的描述
- 以构造器的 prototype 属性(注意与私有字段[[prototype]]的区分)为原型,创建新对象;
- 将 this 和调用参数传给构造器,执行;
- 如果构造器返回的是对象,则返回,否则返回第一步创建的对象。
代码大概这样
// 构造器函数
let Parent = function (name, age) {
this.name = name;
this.age = age;
};
Parent.prototype.sayName = function () {
console.log(this.name);
};
//自己定义的new方法
let newMethod = function (Parent, ...rest) {
// 1.以构造器的prototype属性为原型,创建新对象;
let child = Object.create(Parent.prototype);
// 2.将this和调用参数传给构造器执行
let result = Parent.apply(child, rest);
// 3.如果构造器没有手动返回对象,则返回第一步的对象
return typeof result === 'object' ? result : child;
};
//创建实例,将构造函数Parent与形参作为参数传入
const child = newMethod(Parent, 'echo', 26);
child.sayName() //'echo';
//最后检验,与使用new的效果相同
child instanceof Parent//true
child.hasOwnProperty('name')//true
child.hasOwnProperty('age')//true
child.hasOwnProperty('sayName')//false
Object.create(person) 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 简而言之,就是传入的person是创建出来对象的__proto__属性
缺点:每次使用构造函数,构造函数里的方法会重新创建,占用内存空间
解决方法
function Person(name,age,job){
this.name = name
this.age = age
this.job = job
this.sayName = sayName
}
function sayName(){
console.log(this.name)
}
var person = new Person('joker','15','歌手')
缺点:暴露了全局方法,后期不易维护
3.原型模式
function Person(){}
Person.prototype.name = '薛之谦'
var person1 = new Person()
console.log(person1.name) // 薛之谦
优化
function Person() {}
Person.prototype = {
constructor: Person,
name: '薛之谦',
getName: function () {
console.log(this.name);
}
};
var person1 = new Person();
console.log(person1.name) // 薛之谦
缺点:所有的属性和方法共享
4.组合模式
function Person(name) {
this.name = name;
}
Person.prototype = {
constructor: Person,
getName: function () {
console.log(this.name);
}
};
var person1 = new Person();