首先来理解一下什么事对象:ECMA-262是这样定义的“无序属性的集合,其属性能够包含基本值、对象或者函数”,也就是说,对象是‘名/值’对的集合。数组
var person=new Object(); person.name="Jake"; person.age=18; person.sayName=function(){ alert(this.name); }
上面的例子建立了一个名为person的对象,并为它添加了两个属性:name、age和一个方法sayName。其中sayName用于显示this.name(将被解析为person.name)的值。闭包
咱们来看一段代码:app
var add=function(a,b){ return a+b; }
函数字面量包含4个部分,分别是:函数
函数字面量能够出如今任何容许出现的地方,也能够定义在其余函数中。一个内部函数除了能够访问本身的参数和变量,同时它也能自由地访问它的父函数的变量和参数。经过函数字面量建立的函数对象包含一个链接到外部上下文的连接。这被称为闭包this
闭包这个概念是js这门语言中一个很是重要并且是很难掌握的知识点!
这里只能浅显地解释一下什么是闭包
咱们用一些代码来解释这个定义:prototype
function foo(){ var a=2; function bar(){ console.log(a); } return bar; } var baz=foo(); baz();//2 <--这就是闭包的效果
函数bar()的词法做用域可以访问foo()内部做用域,而后将bar()函数自己看成一个值类型进行传递。
在foo执行后,其返回值 bar()赋值给变量baz并调用baz(),实际上只是经过不一样的标识符引用调用了内部的函数bar()。
在foo执行后,foo内部做用域不会被销毁,由于一直都是bar()自己在使用,所哟foo内部做用域依然存在且可以一直存活,以供bar随时进行引用。
bar依然对该做用域保持引用,而这个引用就叫做闭包。code
做用域的做用:控制着变量与参数的可见性以及生命周期。
定义在函数内部的参数和变量在函数外部是不可见的,而在一个函数内部任何位置定义的变量,在函数内部任何位置均可见。对象
var f00=function(){ var a=3,b=5; var bar=function(){ var b=7,c=11; //此时a=3,b=7,c=11; a+=b+c; //此时a=21,b=7,c=11; }; //此a=3,b=5,c没有定义; bar(); //此时a=21,b=5; }
调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。js提供了四种调用模式:方法调用模式、函数调用模式、构造器调用模式以及apply调用模式。生命周期
当一个函数被保存为对象的一个属性是,咱们称之为方法。当一个方法被调用时,this被绑定到该对象,当对象与方法用“.”来链接时,那么它就被看成一个方法来调用了。ip
var person={ name:"Jake", age:18, sayAge:function(age){ this.age=age; } }; person.sayAge(19); docunment.writeln(person.age);//19
2.函数调用模式
当一个函数并非一个对象的属性时,那么它就是被看成一个函数来调用的
var myobject={ } //添加一个新的方法 myObject.do=function(value){ this.value=value; var that=this; var helper=function(){ that.value=that.value+that.value; }; helper(); } myObject.do(3); console.log(myObject.value)//6
这里面遇到一个问题,就是在helper函数内部的this指向的时这个函数本省,而不是全局对象。咱们找到一个很好的解决方法,那就是将this赋值给一个全新的变量that,那么内部函数就能够访问到this,这样就避免了内部函数里面的this错误的绑定。
3 构造器调用模式
一个函数,若是建立的目的就是但愿结合new前缀来调用,那就被称为构造函数
若是一个函数前面带上new来调用,那么就会建立一个链接到该函数的prototype(原型)成员的新对象,同时函数中的this会绑定到这个新对象中。
var Myobject=function(string){ this.status=string; } Myobject.prototype.get_status=function(){ return this.status; } //建立实例 var newObj=new Myobject("Hello !"); console.log(newObj.get_status()); //Hello !
这里要特别注意:按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。
4.Apply调用模式
Apply方法让咱们构建一个参数组传递给调用函数。它容许咱们选择this的值。Apply方法接受两个参数,第一个要绑定给this的值,第二个就是参数数组。
var array=[3,4]; var sum=add.apply(null,array);//sum值为 7
var statusObj={ status:'Hello' }; var status=Quo.prototype.get_status.apply(statusObj); //status值为‘Hello’
function SpeciallArray(){ var values=new Array(); values.push.apply(values,arguments); values.toPipedString=function(){ return this.join("|"); } return values; } var color=new SpeciallArray("blue","yellow","red"); console.log(colo.toPipedString); //"blue|yellow|red"