这一段时间都在回顾和总结之前JS中一些比较重要的内容,再次写个日记,记录下
面向对象的三大特征:
1.封装
2.继承
3.多态
封装
封装是指创建一个对象集中保存一个事物的属性与功能:
封装对象有三种方式:
:直接用{}
var obj = {}
var obj1 = {
name: '本泽锅',
foo: function() {
console.log(`I'm ${name}`)
//这里直接用name会报错,Uncaught ReferenceError: name is not defined
//原因就是对象的{}不是作用域,函数foo的作用域链只有自己和顶层的window,显然会报错
//解决方法:
console.log(`I'm ${this.name}`)
//这里就是 this的第一种情况:在普通函数中的this,指向的是调用当前函数的.前的对象
}
}
console.log('obj', obj)
console.log('obj1', obj1)
:通过new关键词新建对象
var obj = new Object()
console.log('obj',obj)
var obj1 = new Object()
obj1.name = '本泽锅'
:通过构造函数的方式
function Student (name,foo) {
//将来要加入到新对象中的属性和方法
this.name = name
this.foo= foo
//这里就是 this的第二种情况:在构造函数中的this,指向的是new创建的新对象
}
// 实例化1
var obj = new Student()
console.log('obj',obj)
// 实例化2
var obj1 = new Student('本泽锅',function (){
})
console.log('obj1',obj1)
obj1.foo()
总结: 通过构造函数的方式创建对象 一共干了4件事
1.创建了一个新的空对象。
2.让子对象继承构造函数的原型对象。(将子对象的隐式原型__proto__指向创建该构造函数的显示原型prototype上)
3.调用构造函数,将this替换为新对象,通过强行赋值的方式为新对象添加属性和方法。
4.返回新对象的地址值。
继承
继承是父对象中的成员,子对象无需重复创建,就可以直接使用。
js中的几种都是通过原型对象来实现的。
原型对象:替所有子对象集中保存共有属性和方法的父对象。
概念:每一个构造函数都有一个显示原型ptototype.
每一个对象都有一个隐式原型proto,对象的隐式原型指向创建该构造函数的显示原型
当我们通过构造函数实例化一个对象的时候,就会自动将子对象的隐式原型指向创建该构造函数的显示原型,这样就达到了继承的目的。
原型执行规则
当我们获取对象的属性或者方法时,首先在自身查找,如果有的话就使用,如果没有的话,就自动去隐示原型proto中去查找,而隐示原型会指向创建该对象构造函数的显示原型prototype去查找
原型链
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的proto隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的proto中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链,直到找到顶端Object的显示原型prototype,而Object的显示原型prototype中隐示原型proto为null,这样就停止了。
向原型对象中添加共有属性和方法:
function Student (name,foo) {
this.name = name
this.foo= foo
}
//只能通过强行赋值的方法
Student.prototype.location= '武汉'
Student.prototype.study=function(){
console.log(this.name,'student')
//这里就是 this的第三种情况:原型对象中共有方法里的this,将来调用这个共有方法的.前的那个子对象
}
多态:
同一个函数,在不同情况下表现出的不同的状态。
面向对象小结:
1、封装: 创建对象,2种:
如果只创建一个对象: {} 如果反复创建多个相同结构的对象: 构造函数
2、继承: 所有子对象共用的属性值和方法,都要 放在构造函数的原型对象中
3、多态: 重写: 只要觉得从父对象继承来的成员 不要用,都在子对象中重写同名成员
this的几种情况:
1. obj.fun() this->.前的obj对象
2. new构造函数() this->new正在创建的新对象
3. 构造函数.prototype.fun=function(){}
因为将来原型对象中的方法,都是”子对象.fun()”方式调用。 所以,this->将来调用这个fun函数的.前的某个子对象
4. fun()、匿名函数自调和回调函数中的 this->window
5. button.onclick=function(){}或button.addEventListener(“click”,function(){...}) DOM事件处理函数里的
this-> 当前正在出发事件的.前的DOM元素对象。
6. 箭头函数中的this->当前函数之外最近的作用域中的this
- 几乎所有匿名函数都可用箭头函数简化
- 箭头函数是对大多数匿名函数的简写
箭头函数底层相当于.bind() 永久绑定外部this
7. 改变this的指向
其实,对于this,我们不一定逆来顺受
• - 可用call或apply,临时替换一次函数中的this
• - 可用bind,永久替换函数中的this
总结:
• a. 只在一次调用函数时,临时替换一次this: call
• b. 既要替换一次this,又要拆散数组再传参: apply
• c. 创建新函数副本,并永久绑定this: bind