1.自我执行函数
(匿名函数)();
; (Function(形参){
Alert(“1”);
})(实参);
要注意,在代码的前后都要加上分号,防止代码会压缩合并后缺少分号而报错。
这种形式的代码比较优雅,在业内公认的写法
2.闭包;
闭包是一种现象,没有一个具体的概念。
例子:function box(){
var a=0;
renturn function(){
a++;
renturn a ;
}
}
var a=box( );
a( );
a( );
alert(a( ));
什么是闭包?
通俗的来说就是函数里面套函数,里面形成了一个闭包。
当一个函数返回值是一个函数时,我们可以通过这个函数,这个返回值的函数形成了闭包。
闭包的作用:
在函数的外部访问内部的变量。
因为变量会驻留在内存当中,所以会延长变量的使用周期。
闭包的缺点:
大量耗费内存资源
因为变量会驻留在内存中得不到释放,在ie浏览器中会造成内存的泄露。
封闭作用域的几种格式:
(function( ){ }) ( );
;(function( ){ })();
+(function( ){ })();
-(function( ){ })();
闭包的使用场景:
(1)匿名函数自调用,全局变量私有化,封闭空间,避免了变量之间命名的相互影响;
(2)作用域链
3.原型链
prototype(原型)
创建一个函数的时候,这个函数自动才内存中开辟了一个独立的空间来存放这个原型对象的数据。
只有函数才有原型对象
实例对象,没有原型对象。 Var str=new String(“fadfadfdffdf”);
但是实例对象指向了构造函数的原型对象。
如何指向?
但是原型与实例对象之间是有某种联系的,就是通过”__proto__”;
当我们用new 关键字去构建一个实例对象的时候,会自动的产生一个指针。那就是__proto__
这个指针与构造函数的原型对象产生了联系,这个时候实例对象可以访问构造函数的原型对象下面的方法和属性。
constructor(n. 构造函数;构造器;建造者):
这个也是一个指针,这个指针在构造函数的原型对象里,也是自动生成的。constructor指向构造函数本身,主要用于实现继承。
什么是原型链?
原型链就是实力对象的指针与构造函数的原型对象产生了联系,原型下又有一个指针,原型下的指针指向object(父类或者超类);
实例对象访问属性和方法的原则:
先查找实例,实例没有就去原型,去原型下面去查找,如果原型没有就去超类去查找,超类也没有就返回一个undefined
实例- ->prototype- ->超类- ->(如果没有返回undefined)
Object类的提供的方法和关键字:
实例对象,hasOwnProperty( “属性或者方法名”);如果没有在实例中有,返回有true.如果没有返回false
in关键字:
属性in实例对象,返回true表示有属性,返回false没有这个属性。没有精确到是实例还是原型。
封装函数查找原型是否有某个属性。
function isHasProperty(obj,attr){
return !obj.hasOwnProperty(attr) && attr in obj;
}
构造函数.prototype.isPrototypeOf(实例对象);检测实例对象是否是属性该构造函数的实例对象。
delete关键字:
delete关键字:
(实例对象.属性) 只能删除实例中的属性,无法删除原型下的属性。
面向对象的三个特征(封装,继承,多态)
封装:封装一些功能和一些属性给每个对象使用
继承:子类可以继承一些属性和方法
多态:js中没有多态的说法
4.继承
父类也叫超类
a.改变父类的this执行环境事件继承。
缺点:无法继承父类的原型下的属性和方法(原型下一般保存的是方法);
b.使用call( )和apply( )实现继承
(1).使用call( )改变this指向
function Son(name,age,money){
Father.call(this,name,age,meney)
}
缺点:无法继承父类的原型下的属性和方法;
(2).使用apply( )改变this指向
function Son( ){
Father.apply(this,argument)
}
缺点:无法继承父类的原型下的属性和方法;
c.原型链实现继承
function(){};
Son,prototype=new Father( “值1”,”值2”)
优点:
解决了无法继承父类的原型下的属性和方法的问题
缺点:
无法传参
所有的实例对象共享了所有的属性和方法。
如何解决这个问题?
利用混合继承?
什么是混合继承?
混合继承就是利用原型链跟继承
function Son( ){
//实现实例继承
Father.apply(this,argument)
}
//实现原型继承
Son.prototype=Father.prototype;
当给子类原型下添加一个新的原型方法的时候父类也会获取到这个方法。这是不科学的。原因是当父类的原型赋值给子类的时候,子类的constructor会指向父类的constructor,从而造成给子类原型添加方法的时候父类就会有这个方法。
产生了一个寄生构造?
function Son(){
//实现实例继承
Father.apply(this,arguments);
};
//实现原型继承
heritPrototype(Son,Father);
function heritPrototype(subType,superType){
var proto = Object.create(superType.prototype);
proto.constructor = subType;
subType.prototype = proto;
}
优点:
混合继承解决了继承跟原型链继承的所有问题
缺点:
子类的counselor指向被修改了