面向对象
-
面向对象的基本特征
1.继承
2.封装
3.多态 -
创建对象的方法
1.基本方法
缺点:每创建一个方法都要把这些代码重复一遍,对象属性发生改变会影响到所有的对象,不利于维护
let player = new Object()
player.name = 'cyt'
player.start = function() {
console.log('say hello')
}
2.工厂模式
缺点:工厂模式、 基本方法都⽆法识别对象类型,⽐如 Player 的类型只是 Object
function createFn() {
let player = new Object()
player.name = 'cyt'
player.start = function() {
console.log('say hello')
}
return palyer
}
3.构造函数
缺点:通过this添加的属性和方法都是指向该对象的,但是每实例化一个对象,属性和方法都会在内存中复制一份,造成内存浪费
优点:更改一个对象的属性,其他对象不受影响
function player() {
this.name = 'cyt'
this.start = function() {
console.log(name + 'say hello')
}
}
let p1 = new player()
4.原型
缺点:更改一个对象属性,其他的实例化对象都会受影响
优点:通过原型继承的方法并不是自身的,这样只会在内存中创建一份,实例化的对象都会指向这个prototype
function player() {
this.name = 'cyt'
}
player.prototype.start = function() {
console.log(name + 'say hello')
}
let p1 = new player()
-
列New 关键字做了什么
1.构造函数通过new创建了对象
2.这个对象的proto === 这个构造函数的prototype
3.将this指向这个新创建的对象
4.返回一个新对象- 4.1如果构造函数中没有显式返回值,则返回this
- 4.2如果构造函数中有显式返回值,是基本类型(number,string,boolean...)那么返回的还是this
- 4.3如果构造函数中有显式返回,返回的是object型,则返回这个对象
如何实现一个new
// 如何手动实现一个new
function player(name) {
this.name = name
}
let p1 = new player('cyt') // 通过new实现的
let p2 = mockFn(player, 'cyt') // new的模拟函数
function mockFn() {
// 可以隐式接收参数 arguments = [player, 'cyt']
let o = new Object() // 创建一个实例对象
let functionConstructor = [].shift.call(arguments) // 把player推出,arguments = ['cyt']
o.__proto__ = functionConstructor.prototype // 实例的__proto === 构造函数的prototype
let resultObject = functionConstructor.apply(o, arguments) // this指向新创建的对象o
return resultObject === 'object' ? resultObject : o
}
console.log(p1) // player { name: 'cyt' }
console.log(p2) // player { name: 'cyt' }