1 JS对象相关
- 构造函数和原型基础
//在es6之前,面向对象是通过构造函数实现的,Es6才有类的概念
//复习 js创建对象的三种方式
//1.利用Object()
let obj1 = new Object()
//2.利用对象字面量
let obj2 = {}
//3.利用构造函数
function Star (uname, age) {
this.uname = uname
this.age = age
this.sing = function () {
console.log('sing')
}
}
//ari bri都是对象
let ari = new Star('ari', 18)
let bri = new Star('bri', 19)
ari.sing() // sing
//静态方法
Star.sex = 'woman'
console.log(Star.sex) //woman
console.log(ari.sing === bri.sing) //false sing方法存放的内存空间不一样
//每一个构造函数都有一个原型对象prototype
//一般把公共属性定义在构造函数里面 把公共方法定义在原型对象上 这也是es6类的思想
Star.prototype.sing2 = function () {
console.log('sing')
}
console.log(ari.sing2 === bri.sing2) //true sing方法存在原型对象上,ari.sing2和bri.sing2指向同一地址
console.log(ari.__proto__ === Star.prototype)//true 两者是一样的 因为有__proto__的存在才会去prototype上查找sing2方法
//接下来重写一下Star的原型对象
Star.prototype = {
constructor: Star,
//如果用的是Star.prototype = 对象的形式,必须将constructor指回Star,否则Star的原型对象(以及Star实例的__proto__)内部构造函数丢失
sing2: function () {
console.log('sing')
},
movie: function () {
console.log('movie')
}
}
let cri = new Star('cri', 20)
console.log(cri.__proto__)
console.log(Star.prototype)
/* {constructor: [Function: Star] { sex: 'woman' },
sing2: [Function: sing2],
movie: [Function: movie]
}*/
console.log(Star.prototype.__proto__ === Object.prototype)//true 原型对象也是对象,也有自己的对象原型__proto__,指向Object的原型对象
console.log(Object.prototype.__proto__)//null 说明原型链已经到头了
//所以 要调用某方法时 先在实例对象的属性里找 如果没有 顺着__proto__ 就去构造函数的原型对象上找
//如果还没有 顺着__proto__ 再找, ......一直到Object上的原型对象上找 还没有则返回null 这就是原型链的基本概念
//同样的 Object原型对象也有对应的Object构造函数,同样要注意constructor指回问题
//构造函数的this指向的是实例对象,原型对象函数里的this指向的依然是实例对象(因为都是实例调用的函数)
- 原型对象可以扩展内置对象方法
Array.prototype.sum = function () { //注意这里不能用Array.prototype = 对象重写 不允许
let sum = 0
for (let i = 0; i < this.length; i++) {
sum += this[i]
}
return sum
}
let arr = [1, 2, 3]
let arr1 = new Array(11, 22, 33)
console.log(arr.sum())//6
console.log(arr1.sum())//66
- 组合继承(es6之前的继承方法)
//组合继承
function A (uname, age) {
this.uname = uname
this.age = age
}
A.prototype.money = function () {
console.log(1000)
}
function B (uname, age, score) {
A.call(this, uname, age) //call方法使用了类A的构造函数
this.score = score
}
B.prototype = new A() //注意不要写B.prototype = A.prototype 因为这两个protoype指向同一地址
B.prototype.constructor = B //prototype = 对象的写法 要指回构造函数
B.prototype.exam = function () {
console.log('exam')
}
let b = new B('ari', 18, 100)
console.log(b)
b.exam()
b.money() //调用money()方法的过程 先看b实例对象没有 去B原型对象找 还没有 再去A对应的实例对象找__proto__ 最终在A的原型对象上找到
console.log(A.prototype)
/*B { uname: 'ari', age: 18, score: 100 }
exam
1000
{ money: [Function (anonymous)] }*/
2 总结
大致列举了es6之前js的继承和面向对象相关内容