1.1 创建对象的三种方式:
- 对象字面量
var obj1 = {}
- new Object()
var obj2 = new Object()
- 自定义构造函数
function Star(name,age){
this.name = name
this.age = age
this.sing = function(){
console.log('唱歌');
}
}
// 对象实例化
let lll = new Star()
1.2 构造函数
- 特殊函数,用赖初始化对象,即为对象成员变量赋初始值,与
new
一起使用 - 可将对象中的一些公共的属性和方法抽取出来,封装到该函数中
- 首字母一般大写
new在执行时会做的四件事:
- 在内存中创建一个新的空对象
- 让this指向这个新的对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象(所以构造函数里面不需要return )
- 静态成员:只能构造函数本身访问
- 实例成员:只能由实例化的对象访问
function Star(name,age){
// 实例成员 name age sing
this.name = name
this.age = age
this.sing = function(){
console.log('唱歌');
}
}
//静态成员
Star.sex = '男'
1.3 构造函数的问题
- 存在浪费内存的问题
为了节省内存,如何让所有实例对象使用同一个函数?
解决:
- 构造函数的原型
prototype
- 通过原型分配的函数是所有对象共享的
什么是原型?
- 一个对象,称prototype为原型对象
原型的作用是什么?
共享方法
// 对象实例化
let aaa = new Star()
let bbb = new Star()
// sing方法直接定义在构造函数上
// false 开辟了两个不同的空间 地址不同
console.log(aaa.sing() === bbb.sing());
//sing方法定义在原型上
Star.prototype.sing()=function(){
console.log('唱歌');
}
//true 两个实例指向同一个地址
console.log(aaa.sing() === bbb.sing());
- 一般情况,公共属性定义到构造函数里面,公共方法放到原型对象上
问题:为什么实例对象aaa就可以使用到构造函数原型上的方法呢?
- 实例对象上的原型
__proto__
- 指向了构造函数的
prototype
- 对象原型
__proto__
和原型对象prototype
是等价的 - 只是为对象查找机制提供一个方向,它是非标准属性,实际开发中一般不用,它只是内部指定
原型对象prototype
console.log(aaa.__proto__ === Star.prototype); //true
NOTICE:
- 对象原型(__ proto__)和构造函数(prototype)原型对象里面都有一个
construct属性
,指向构造函数本身 - 该属性主要用于记录实例对象引用于哪个构造函数
console.log(aaa.__proto__.costructor === Star.prototype.costructor); //true
- 有些情况下,需要手动利用constructor属性,指回原来的值
- 比如说修改原来的原型对象并给其赋值另一个对象
//这种写法会导致prototype重写
Star.prototype = {
sing:function{
console.log('sing');
},
movie:function(){
console.log('movie');
}
}
手动指向:
Star.prototype = {
costructor:Star,
sing:function(){
console.log('sing');
},
movie:function(){
console.log('movie');
}
}
1.4 构造函数、实例、原型对象之间的关系
1.5 原型链
- Star原型对象prototype
console.log(Star.prototype);
1.6 JavaScript的成员查找机制
- 当访问一个对象的属性(包括方法)时,首先查找这个
对象自身
有没有该属性 - 如果没有就查找它的原型(也就是_ proto_ 指向的
prototype原型对象
) - 如果还没有就查找原型对象的原型(
Object的原型对象
)。 - 依此类推一直找到Object为止 (
null
) - _proto_对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
- 构造函数中的this指向的是对象实例
1.7 原型链的作用
- 扩展内置对象方法
Array.prototype.sum = function () {
var sum = 0
for(let i = 0;i<this.length;i++){
sum += this[i]
}
return sum
}
let arr = [1,2,3]
console.log(arr.sum());
console.log(Array.prototype);