002
主要熟悉代码的逻辑,ES6中都是使用class代替构造函数加原型对象的方式
一、构造函数
ES6之前没有类的概念,需要使用构造函数来进行面向对象的编程,使用function来初始化对象,可以把对象中的一些公共的属性和方法抽取出来,封装到函数中,在使用new关键字进行实例化。
1.静态成员和实例成员
实例成员可以看成是构造函数定义时声明的成员,需进行实例化之后,使用m.xxx来访问;静态成员是在构造函数本身添加的成员,需要动态的添加,只能通过Student.xxx来调用。
//构造函数
function Student(){
this.name = '张三';
this.age = '12';
this.learning = function (){
console.log('热爱学习');
}
}
//实例化
var m = new Student();
//访问实例成员
console.log(m.name);
//添加静态成员
Student.sex = '男';
//访问静态成员
console.log(Student.sex);
2.构造函数的缺陷
每实例化一个对象就,对象中的方法会单独开辟一个内存空间,资源浪费。因此就需要构造函数原型。
一、原型对象与原型链
1.构造函数原型prototype
每个构造函数中都存在一个原型属性,其本质就是一个对象。
通过把函数体添加至原型对象中,实现每实例化一个对象,共用一个函数,这样就避免了上述的缺陷
Student.prototype.learning = function (){
console.log('热爱学习');
}
此外,之所以可以使用原型对象中的方法,是因为实例化一个对象之后,在其中自动添加了一个__proto__(称为对象原型)的属性,其指向构造函数中的原型对象,即这里m.__proto__和Student.prototype是等价的。
2.constructor构造函数
上面的m.__proto__和Student.prototype中都有一个constructor,含义是表征原型对象和对象原型是由哪一个构造函数衍生出来的,打印m.proto.constructor即返回最开始创建的那个构造函数。
为了格式完整,往往使用下面的方式创建原型对象:
Student.prototype = {
constructor: Student,
learning: function (){
console.log('热爱学习');
},
reading: function (){
console.log('喜欢读书');
}
}
因为是prototype等于一个对象,这把原来的值覆盖掉了,因此需要加一句constructor: Student,来指向构造函数。
3.“套娃”(原型链)
原型对象本身也是一个对象,其内部也有一个对象原型__proto__,其指向Object原型对象,Object对象通过constructor指向Object构造函数,Object原型对象内也有一个__proto__,指向为null。上述即为原型链
4.对象成员查找规则
对象实例→原型对象→Object对象→null,若都有则采取就近原则,使用前一级的方法
5.用原型对象扩展内置对象方法
实际开发中不会用到,可以看看里边的逻辑
Array.prototype.square_sum = function (){
var sum = 0;
for (var i=0;i<this.length;i++){
sum += this[i]*this[i];
}//this指向调用该方法的实例对象
return sum;
}
三、继承
1.call()
使用格式function.call(this指向,参数1,参数2…)
function fn(x,y){
console.log(x+y);
console.log(this);
}
var o = {
name: 'andy'
};
fn(1,2)
fn.call(o,1,2);
2.借用父构造函数继承属性
主要需要使用call方法改变函数的指向
function Father(fname, fage){
this.name = fname;
this.age = fage;
}
function Son(sname, sage){
Father.call(this, sname, sage);
}
var s = new Son("ZRJ",18);
console.log(s.age);
3.借用新建实例继承方法
function Father(fname, fage){
this.name = fname;
this.age = fage;
}
Father.prototype.money = function (){
console.log('可以挣钱');
}
function Son(sname, sage){
Father.call(this, sname, sage);
}
Son.prototype = new Father();//相当于新开辟了一个地址空间,因此不会影响父构造函数的原型对象
Son.prototype.constructor = Son;//由于上面改变了指向,需要使用constructor进行重新指向
var s = new Son('ZRJ',19);
s.money();
4.ES6=>类
ES5基于构造函数加原型对象进行面向对象的编程,ES6中使用类(语法糖),其本质还是一个函数,类中也有原型对象、原型对象中有constructor指向类本身…,新的class写法只是让对象原型的写法更加清晰、更具面向对象的特点。
三、ES5的新增方法
1.数组方法:forEach(), filter(), some()
感觉forEach()主要用来渲染界面,filter()用来筛选,用的比较多
var arr = [2,2,3];
//forEach()
//a代表每一个元素的值、b代表每一个元素的索引号、c代表数组本身
arr.forEach(function (a, b, c){
})
//filter()
//用于数组的筛选,参数同上,return加返回条件,返回的是一个数组
var newArr = arr.filter(function (a, b, c){
return a >= 3;
})
//some()
//查找数组中是否有满足条件的元素,返回一个布尔值,找到即终止
var result = arr.some(function (value, index, array){
return value === 2;
})
2.字符串方法:trim()
var str = ' 123 ';
var newStr = str.trim();
3.对象方法:Object.defineProperty()
Object.defineProperties(obj, 'name', {
value: 'zzrrjj',//改变属性的值,若没有则为添加属性
writable: true,//设置属性是否可重写,默认false
enumerable: true,//设置是否是可被枚举,默认false
configurable: true//设置属性是否可被删除以及是否可被再次修改特性,默认false
})