前 言
OOP
JavaScript中OOP——>>>面向对象中的继承/闭包
1.1面向对象的概念
使用一个子类继承另一个父类,子类可以自动拥有父类的属性和方法。
>>> 继承的两方,发生在两个类之间。
1.2JS模拟实现继承的三种方式:
首先,了解一下call/apply/binb:通过函数名调用方法,强行将函数中的this指向某个对象;
call写法: func.call(func的this指向的obj,参数1,参数2...);
apply写法: func.apply(func的this指向的obj,[参数1,参数2...]);
binb写法: func.binb(func的this指向的obj)(参数1,参数2...);
call与apply的唯一区别:在于接收func函数的参数方式不同。call采用直接写多个参数的方式,而apply采用是一个数组封装所有参数。
call写法: func.call(func的this指向的obj,参数1,参数2...);
apply写法: func.apply(func的this指向的obj,[参数1,参数2...]);
binb写法: func.binb(func的this指向的obj)(参数1,参数2...);
call与apply的唯一区别:在于接收func函数的参数方式不同。call采用直接写多个参数的方式,而apply采用是一个数组封装所有参数。
① 扩展Object实现继承
1:定义父类
function Parent(){}
2:定义子类
funtion Son(){}
3:通过原型给Object对象添加一个扩展方法。
Object.prototype.customExtend = function(parObj){
for(var i in parObj){
// 通过for-in循环,把父类的所有属性方法,赋值给自己
this[i] = parObj[i];
}
}
4:子类对象调用扩展方法
Son.customExtend(Parent);
① eg:
1 // 1.定义父类 2 function Person(name,age){ 3 this.name = name; 4 this.age = age; 5 this.say = function(){ 6 alert(this.name+":"+this.age); 7 } 8 } 9 // 2.定义子类 10 function Student(no){ 11 this.no = no; 12 this.add = function(a,b){ 13 alert(a+b); 14 } 15 } 16 function Programmer(lang){ 17 this.lang = lang; 18 this.codding = function(){ 19 alert("我爱敲代码!敲代码使我快乐!"); 20 } 21 } 22 // 3.通过原型给Object对象添加一个扩展方法。 23 Object.prototype.customExtend = function(parObj){ 24 for(var i in parObj){ 25 // 通过for-in循环,把父类的所有属性方法,赋值给自己 26 this[i] = parObj[i]; 27 } 28 } 29 30 var p = new Person("小明","18"); 31 var s = new Student("0001"); 32 s.customExtend(p);//现在s继承了p的所有属性和方法。 33 console.log(s) 34 35 var pro = new Programmer("JavaScript"); 36 pro.customExtend(p); 37 console.log(pro) 38 39 40 41
② 使用call/apply/binb.
1:定义父类
funtion Parent(””,””,””){}
2:定义子类
function Son(””,””,””){}
3:在子类中通过call方法/apply/binb方法去调用父类。
function Son(){
Parent.call(this,””,””,””);// Parent.apply(this,[””,””,””]);//Parent.binb(this)(””,””,””);
}
② eg:
1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 this.say = function(){ 5 alert("我叫:"+this.name+";今年:"+this.age+"岁"); 6 } 7 } 8 9 /** 文档注释,调用函数时,可以看到注释内容。 10 * 11 * no:学员编号 12 * stuName:学员姓名 13 * stuAge:学员年龄 14 */ 15 function Student(no,stuName,stuAge){ 16 17 this.no = no; 18 Person.call(this,stuName,stuAge); 19 // 执行上述代码,相当于将下面的代码执行一遍。并且把原来Person类的this直接替换为Stundet的this(当实例化Student时的那个对象) 20 21 // this.name = "张三"; 22 // this.age = 14; 23 // this.say = function(){ 24 // alert("我叫:"+this.name+";今年:"+this.age+"岁"); 25 // } 26 } 27 28 var stu = new Student(12,"zhangsan",14); 29 stu.say(); 30 31 console.log(stu) 32 33 //Person("zhangsan","123");
③ 使用原型继承
1:定义父类
function Parent(””,””,””){}
2:定义子类
function Son(””,””,””){}
3:把在子类对象的原型对象声明为父类的实例。
Son.prototype = new Parent(””,””,””);
③ eg:
1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 this.say = function(){ 5 alert("我叫:"+this.name+";今年:"+this.age+"岁"); 6 } 7 } 8 9 /** 文档注释,调用函数时,可以看到注释内容。 10 * 11 * no:学员编号 12 * stuName:学员姓名 13 * stuAge:学员年龄 14 */ 15 function Student(no){ 16 this.no = no; 17 } 18 19 Student.prototype = new Person("张三",14) 20 21 var stu = new Student(12); 22 23 stu.say(); 24 25 console.log(stu) 26 27 //Person("zhangsan","123");
1.3面向对象中的闭包
1、 全局变量:函数外声明的变量
局部变量:函数内声明的变量
在JS中,函数为唯一的局部作用域,而if、for等其他{}没有自己的作用域
所以,函数外不能访问局部变量。其实,变量在函数执行完毕以后,占用的内存就被释放。
2、如何访问函数私有变量?
JS中,提供了一种"闭包"的概念:在函数内部,定义一个子函数,可以用子函数访问父函数的私有变量。执行完操作以后,将子函数通过return返回。
function func2(){
var num = 1;
function func3(){
var sum = num+10;
alert(sum);
}
return func3;
}
var f = func2();
f();
3、闭包的作用:
① 访问函数的私有变量;
② 让函数的变量始终存在于内存中,而不被释放。