继承
js实现继承的方式依靠原型链完成
在js里,被继承的函数称为超类型(父类,基类也行,其他语言叫法),继承的函数称为子类型(子类,派生类)。
案例一
function Ball(_age) {
this.age=_age; //this 在使用Call以后就是带入的冒充对象
}
Ball.prototype={
run:function () {
console.log("run")
}
};
function OneBall(_age) {
Ball.call(this,_age) //this OneBall实例化
}
OneBall.prototype=new Ball(); //继承父类
OneBall.prototype.run=function () {
console.log("walk")
};
var ball1=new Ball(300);
ball1.run();
var ball=new OneBall(300);
ball.run();
案例二
function Ball(_age) {
console.log("Balls_2")
this.age=_age;
this.run=function () {
console.log("run")
}
}
function Balls(_age) {
console.log("Balls_1")
Ball.call(this,_age);
}
function extendsTo(subClass,superClass) {
function F(){}
F.prototype=superClass.prototype;
subClass.prototype=new F();
subClass.prototype.constructor=subClass;
subClass.superClass=superClass.prototype;
if(superClass.prototype.constructor==Object.prototype.constructor){
superClass.prototype.constructor=superClass;
}
}
extendsTo(Balls,Ball); //第一种继承方法
Balls.prototype=Object.create(Ball.prototype); //第二种继承方法
组合继承:原型链+借用构造函数的模式,这种模式称为组合继承。
原型式继承:这种继承借助原型并基于已有的对象创建新对象,同时还不必因此创建自定义类型。
寄生式继承:把原型式+工厂模式结合而来,目的是为了封装创建对象的过程。
组合式继承:是JS最常用的继承模式:但,组合式继承也有一点小问题,就是超类型在使用过程中会被调用两次:一次是创建子类型的时候,另一次是在子类型构造函数的内部。
混入式继承:有时候我们需要子类拥有多个父类,并且继承他们的所有内容,这个时候我们就需要混入式继承
overrides
override是复写的意思,就是父类中方法已经描述完成,子类继承了父类的内容后,需要重新写父类的方法,这个时候我们把他称为复写。
super
super的概念就是在复写的方法中先执行原有类的该方法,然后再这个基础上添加新的需要执行的内容。
设计模式
设计模式分为三种类型,共23种。
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
类
类是 面向对象程序设计语言中的一个概念。类(Class)实际上是对某种类型的对象定义变量和方法的原型。它表示对现实生活中一类具有共同特征的事物的抽象,是面向对象编程的基础
类的定义1-构造函数法
类的定义2-对象创建法
类的定义3-极简主义法
原型
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象(原型对象)
1.function Ball(){}
2.Ball.prototype={
a:3;
}
3.Ball.prototype.a=3
var ball=new Ball();
console.log(ball)
原型链内的属性不可被枚举
案例一
function Box(){}//声明一个构造函数
Box.prototype.name=”zhang”;//在原型里添加属性
Box.prototype.age=100;
Box.prototype.run=function(){//在原型里添加方法
return this.name+this.age+”运行中……”;
}
//比较一下原型内的方法地址是否一致:
var box1=new Box();
var box2=new Box();
alert(box1.run==box2.run);//true,方法的引用地址保持一致
案例二
function Ball(_age) {
this.age=_age; //this 在使用Call以后就是带入的冒充对象
}
Ball.prototype={
run:function () {
console.log("run")
}
};
function OneBall(_age) {
Ball.call(this,_age)//this OneBall实例化
}
OneBall.prototype=new Ball();
OneBall.prototype.run=function () {
console.log("walk")
};
var ball1=new Ball(300);
ball1.run();
var ball=new OneBall(300);
ball.run();
var ball=new Ball(30);
原型方法
hasOwnProperty() 方法会返回一个布尔值,指示对象是否具有指定的属性作为自身(不继承)属性。
isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。
propertyIsEnumerable() 方法返回一个布尔值,表明指定的属性名是否是当前对象可枚举的自身属性。
枚举就是用for in可以罗列出来的属性
constructor属性,返回一个指向创建了该对象原型的函数引用。需要注意的是,该属性的值是那个函数本身,而不是一个包含函数名称的字符串。对于原始值(如1,true 或 "test"),该属性为只读。
闭包
作用域
全局变量和局部变
var a=6; // 全局变量
function abc(){
coonsole.log(a); //undefined
var a=5; // 局部变量
console.log(a); //5
}
abc();
console.log(a)
闭包的特点和优点
闭包的特点
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
闭包的优点
1.希望一个变量长期驻扎在内存中
2.避免全局变量的污染
3.私有成员的存在
什么是闭包
1.函数内必须返回一个对象或者方法
2.必须是自执行函数
var abc=(function () {
var a=6;
var _e=0;
var obj={a:5};
return {
b:5,
c:function () {
// a+=this.b
return a+this.b;
},
set e(value){
a+=value
_e=value;
},
get e(){
return _e;
},
dispose:function () {
obj=null;
}
}
})();
abc.e=10;
console.log(abc.c());
abc.dispose();
abc=null;
console.log(abc.c());
回调
回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。
回调函数的机制
⑴定义一个回调函数;
⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
function abc(callback) {
callback.apply(null,[])
}
function cde(a,b) {
console.log("a")
}
function efg(c,d,e) {
console.log("b")
}
abc(cde)
abc(efg)
递归
递归函数即自调用函数,在函数体内部直接或间接地自己调用自己,即函数的嵌套调用是函数本身。
直接调用
var i=0;
abc();
function abc() {
i++;
if(i<10){
abc()
}else{
console.log(i)
}
}
间接调用
function fun1(x) {
var z=fun2(x+1)
}
function fun2(s) {
if(s<10){
fun1(s+1)
}else{
console.log(s)
}
}
fun1(2);