JavaScript
一、方法
函数也可以成为对象的属性,如果一个函数作为一个对象的属性保存,那么称这个函数为这个对象的方法,调用这个函树就是调用这个对象的方法。 for in语句:对象中有几个属性,循环体就会执行几次,每执行一次,会将对象中的属性的名字依次赋值给变量。语法:for(var 变量 in 对象){};
< script type= "text/javascript" >
var obj= {
name: "bob" ,
age: 18 ,
gender: "男" ,
address: "xt" ,
} ;
for ( var n in obj)
{
console. log ( n) ;
}
for ( var n in obj)
{
console. log ( obj[ n] ) ;
}
< / script>
二、作用域(scope)
作用域是指一个变量作用的范围; JS中中一共有两种作用域:全局作用域和函数作用域。
全局作用域:直接编写在script标签里的JS代码,都在全局作用域,全局作用域中的变量都是全局变量,在页面的任意部分都可以被访问。全局作用域在页面打开时创建,在页面关闭时销毁。 全局作用域中有一个全局对象window,它由浏览器创建,我们可以直接使用,在全局作用域中,创建的变量都会作为window对象的属性保存。创建的函数都会作为window对象的方法保存。 函数作用域:调用函数时创建函数作用域,函数执行完后,函数作用域销毁。每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的;在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问函数作用域的变量。 变量的声明提前:使用var关键字声明的变量,会在所有的代码执行之前被执行,但是如果声明变量之前不使用var关键字,则变量不会被声明提前。函数作用域中也有声明提前的特性。注意:在函数中,不使用var声明的变量都会成为全局变量 。 函数声明提前:使用函数声明形式创建的函数function 函数名(){},它会在所有代码执行之前就被创建,所以我们可以在函数声明之前调用函数。而使用函数表达式创建的函数var fun=function(){},不会被声明提前,所以不能在声明前调用。 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,如果没有则向上一级作用域中寻找,直到找到全局作用域,如果全局作用域中依然没有找到,则会报错referenceerror。在函数中要访问全局变量,可以使用window对象。 注意:定义形参就相当于在函数作用域中声明了变量。
三、this
解析器在调用函数时每次都会传递一个隐含的参数,这个隐含的参数就是this。this指向的是一个对象 ,这个对象我们称为函数执行的上下文对象 。
< script type= "text/javascript" >
function fun ( ) {
console. log ( this ) ;
}
fun ( ) ;
var a= {
name: "bob" ,
sayname: fun
} ;
console. log ( a. sayname== fun) ;
a. sayname ( ) ;
< / script>
根据函数的调用方法不同,this会指向不同的对象;以函数的形式调用时,this永远都是window,以方法的形式调用时,this就是调用方法的那个对象。
< script type= "text/javascript" >
var name= "candy" ;
function fun ( ) {
console. log ( this . name) ;
}
fun ( ) ;
var a= {
name: "bob" ,
sayname: fun
} ;
var b= {
name: "alice" ,
sayname: fun
} ;
b. sayname ( ) ;
a. sayname ( ) ;
< / script>
四、构造函数
使用工厂方法创建的对象,使用的构造函数都是object,所以创建的函数都是object这个类型,就导致我们无法区分出多种不同类型的对象。
< script type= "text/javascript" >
function createPerson ( name, age, gender ) {
var a= new Object ( ) ;
a. name= name;
a. age= age;
a. gender= gender;
return a;
}
var b= createPerson ( "alice" , 20 , "女" ) ;
var c= createPerson ( "bob" , 20 , "男" ) ;
console. log ( b) ;
console. log ( c) ;
< / script>
构造函数的创建:和普通函数基本相同,不同的是构造函数首字母要大写。 构造函数的调用:普通函数直接调用,而构造函数需要使用new关键字 来调用。 构造函数执行流程: a.立刻创建一个新的对象; b.将新建的对象设置为函数中的this(this指向的是上下文对象),在构造函数中可以使用this来引用新建对象; c.逐行执行函数中的代码; d.将新建的对象作为返回值返回。 使用一个构造函数创建的对象,称为一类对象,也将构造函数称为一个类 ,通过构造函数创建的对象称为类的实例。 使用instanceof可以检查一个对象是否是一个类的实例。语法:对象 instanceof 构造函数。 this:当以构造函数调用时,this就是新创建的那个对象。
< script type= "text/javascript" >
function Person ( name, age, gender ) {
this . name= name;
this . age= age;
this . gender= gender;
this . sayName = function ( ) {
alert ( "hhhhhh" + this . name) ;
}
}
var a= new Person ( "alice" , 18 , "女" ) ;
var b= new Person ( "bob" , 18 , "男" ) ;
console. log ( a) ;
console. log ( b) ;
< / script>
构造函数每执行一次就会创建一个新的sayName方法,并且这些新的方法都是一样的,可以使所有的对象共享同一方法。因此,可以将上面代码更改将sayname方法在全局作用域中定义。 但这样的方式也有很多弊端,将函数定义在全局作用域中,污染了全局作用域的命名空间,而且定义在全局作用域中不安全。
< script type= "text/javascript" >
function Person ( name, age, gender ) {
this . name= name;
this . age= age;
this . gender= gender;
this . sayName= fun;
}
function fun ( ) {
alert ( "hhhhhh" + this . name) ;
}
var a= new Person ( "alice" , 18 , "女" ) ;
var b= new Person ( "bob" , 18 , "男" ) ;
console. log ( a) ;
console. log ( b) ;
a. sayName ( ) ;
b. sayName ( ) ;
< / script>