您的位置:首页 > Web前端 > JavaScript

Js高级笔记

2016-08-02 09:18 351 查看

JS高级笔记

1.作用域问题

变量的寻找从当前域开始往外逐一寻找,直到找到全局域,如果没有找到,则为undefined。

var n = 1;

var s = ‘hello’;

var f = ‘sdhjsk’;

function fn(){

//js执行之前,存在着预编译,会给所有变量申请空间,但是不会

//赋值,因此在执行console.log(n);时,由于var n=3已经预编译 //了,但是并没有赋值,所有输出为undefined

console.log(n);//输出undefined

//首先在函数fn中寻找,发现没有s,再到函数外的域中寻找,找

//到var s = ‘hello’

console.log(s);//输出hello

//给n变量赋值,首先在fn域中寻找,有没有申明n变量

//发现没有,在函数外找到了var n = 1,因此又重新赋值 n=2

n = 2;

var n = 3;

var f = ‘fn f’;

function inner(){

console.log(n);//3

console.log(s);//hello

console.log(f);//undefined

var f = ‘inner f’;

}

inner();

}

fn();

2声明变量var的作用

function t(){


// var 表示申明,但是此处没有var,则直接是赋值,首先会在t函数域 中找是否有d变量,如果没有,则到更外层去找,如果都没有,则在window.d = 5,d因此成为了全局变量。

d = 5

}

3.js词法分析

3.1 js代码的整体运行分为词法分析期、运行期。

3.2 词法分析

第一步:先分析函数参数

第二步:再分析变量申明

第三步:分析函数声明

具体步骤:

0.在函数运行前的一瞬间,生成Action Object(活动对象)

1.1把函数声明的参数,形成AO的属性,参数的值为undefined

1.2接收实参,形成AO相应属性的值

2.分析变量的声明,例如var age,如果AO上已经有age属性,则不做

任何影响,如果没有Age属性,则添加AO属性,值是undefined

3.分析函数声明,如function foo(){ },则把函数赋值给AO.foo属性

注:如果此前有foo属性存在,则被覆盖了

例1

function t3(greet){

var greet = ‘hello’;

alert(greet);//hello

function greet(){

}

alert(greet);//hello

}

t3(‘hi’);

词法分析:

0.生成AO对象 AO={}

1.参数分析 AO={greet:undefined} –>AO={greet:’hi’}

2.变量申明分析,由于AO中有age属性,所有不做任何处理

3.函数greet将覆盖之前AO中的greet变量,因此AO={greet:function

greet(){}}

运行期:

var greet = ‘hello’;//给AO中greet属性赋值,AO={greet:’hello’}

alert(greet) //greet = AO.greet = ‘hello’;

alert(greet) //greet = AO.greet = ‘hello’;

例2

function a(b){

alert(b); //b函数

Function b (){

alert(b);//b函数

}

b();

}

a(1);

词法分析:

0.生成AO对象 AO={}

1.参数分析 AO={b:undefined} –>AO={b:1}

2.变量申明分析,没有变量申明

3.函数b将覆盖之前AO中的b属性, AO={b:function b(){}}

运行期:

alert(b); //b = AO.b = function b(){};

alert(b); //b = AO.b = function b(){};

例3

function a(b){

alert(b); //1

var b = function (){

alert(b);//b函数

}

b();

}

a(1);

词法分析:

0.生成AO对象 AO={}

1.参数分析 AO={b:undefined} –>AO={b:1}

2.变量申明分析,由于之前AO中有b属性,因此不做任何处理

3.没有函数申明,var b = function (){..}这句不是函数申明,算是赋值

语句,因此在运行期执行。

运行期:

alert(b); //b = AO.b = 1 输出1

var b = function (){} //AO={b:function(){}}

所有第二个alert(b)输出是函数b

4.arguments是什么?

4.1 arguments是一个对象,是一个长得很像数组的对象,arguments是函数运行时的实参列表。arguments.callee 表示当前运行的函数。

4.2函数运行时关键的三个对象

Action Object:
4000
在本函数AO上没有的属性,则会继续向外层函数AO 上找,直到全局变量,叫做作用域链。

Arguments:每个函数都有自己的callee,但是不向外层找arguments 的相关属性,即不形成链。

This 一句话,在函数中,谁调用该函数,this表示谁。

5.this到底是谁?

Js中函数的四种调用方法:

(1)普通函数调用:

function t(){
this.xx = 333;

}

t();//window调用函数t,所有this表示this,因此函数执行后

Window.xx = 333;

(2)作为对象的调用方法

Var Obj = {xx:22,yy:11,function t(){alert(this.xx)}};

Obj.t();//this表示obj对象,因此this.xx = obj.xx = 22;

(3)函数作为构造函数调用:

js中没有类的概念,创建对象是用构造函数来完成的,或直接用json格式{}来写对象。

function Dog(name,age){//构造函数

this.name = name;

this.age = age;

}

var dog = new Dog(‘huzi’,2);

//a.系统创建空对象{},把空对象的construtor属 性指向dog函数

/b.把函数的this指向该空对象

//c.执行该函数

//d.返回该对象

(4).函数被call或者apply调用 语法格式:函数.call(对象,参数

1,参数2)此时函数中的this是指的是参数中指定的对象。

有this的操作的函数,如(this.age = xx)的函数不能直接调用而是用new来调用因为直接调用,this表示的是window对象,会污染到全局变量。

6.闭包的概念:

function t1(){

var age = 20;

function t2(){

alert(age);

}

return t2;

}

var temp = t1();

var age = 99;

temp();//打印出来是20

在执行t1函数时,有申明了函数t2,由于t2函数能够访问到age=20

因此当t1函数返回t2时,不仅仅是返回的t2函数,而且还把它周围的变量环境一起返回,形成一个“环境包”,称为闭包。

一句话概括,函数的作用域取决于申明时,而不是调用时。

闭包计数器

多个人开发js程序,需要一个全局的计数器,多个人的函数共同用一个计数器,计数器一直增加。

第一版

function counter(){

var cnt = 0;

function cnter(){

return ++cnt;

}

return cnter;

}

var inc = counter();

inc();

inc();

第二版

var cnt = (function(){

var cnt = 0;

return function(){

return ++cnt

}

})();

第三版(在工作中,一般如何避免全局变量污染和冲突)

1.统一放在一个全局对象,如jquery->//jQuery的计数器插件形式.cnt = (function(){

var cnt = 0;

return function(){

return ++cnt

}

})();

alert($.cnt())

2.每个人用自己的命名空间 其实就是把自己的变量放在一个对象里

var yejiax = {}

yejiaxi.cnt = (function(){

var cnt = 0;

return function(){

return ++cnt

}

})();

7.Js的面向对象

7.1 在js中,有对象,没有类(但是有构造函数),在很多语言中,由类产生对象,但是js的对象不依赖于类。js的对象只是一个“属性字典”,因此我们可以直接造对象,不要类。js中的对象,就是一组属性与值得集合,属性可以任意增减,方法和属性不必区分。

7.2 用构造函数创建对象。

function Dog(){

this.leg = 4;

this.bark = function(){

alert(‘bark’);

}

}

var dog = new Dog();

以上并没有完成面向对象的封装,因为以上对象中的所有都是向外暴露的,

封装表示的是指向外面暴露接口,而里面的变量只能通过这些接口访问。

可以通过闭包的方式来对对象进行封装

function Dog(){

var age = 4//age只有调用getAge的方式获取

this.leg = 4;

this.bark = function(){

alert(‘bark’);

}

this.getAge = function(){

alert(age);

}

}

var dog = new Dog();

8.继承

8.1 js没有类的概念,因此js的继承是不是通过类来实现的

而是通过“原型”的概念来完成的的。

function tiger(){

this.bark = function(){

alert(‘我是百兽之王’);

}

}

var hu = new tiger();

function cat(){

this.climb = function(){

alert(‘我会爬树’);

}

}

var bosi = new cat();

//让tiger继承cat类,但是js做不到,我们明确的对tiger函数指定,用具体的cat对象作为老虎的原型,并创建老虎对象

tiger.prototype = new cat();

var huhu = new tiger();

huhu.climb();

老虎现在自身对象上寻找,没有爬树的方法,去找原型,原型cat对象上有此方法。

Object对象的原型指向null

Cat对象的原型指向普通Object对象

tiger对象的原型指向cat对象

*js的语法非常灵活,不仅可以原型继承,还可以用其他方法,如原型冒充,或复制继承

function Cat(leg,tail){
this.leg = leg;
this.tail = tail;
this.climb = function(){
alert('我会爬树');
}
}

function Tiger(leg,tail,color){
this.parent = Cat;
this.parent.apply(this,arguments);
delete parent;
this.color = color;
}

在用tiger造对象前,用Tiger的语句影响一个空对象{},在此过程中,tiger影响空对象前,先由Cat函数实施影响,因此最终得到的对象是由Cat和Tiger两者共同作用过的一个对象。


*复制继承 把父对象的所有属性,直接复制到自己的对象上

function Cat(leg,tail){
this.leg = leg;
this.tail = tail;
this.climb = function(){
alert('我会爬树');
}
}

function Tiger(color){

this.color = color;
this.extend = function(parent){
for(var key in parent){
this[key] = parent[key];
}
}
}

var tiger = new Tiger('red');
tiger.extend(new Cat());//老虎会爬树了


9.js中的静态方法

构造函数本身也是一个对象

function dog(age){

this.age = age;

}

new dog();//构造函数创造了一个dog对象,

这个构造函数本身也是一个对象。

比如:一个豆浆机,转动(new调用)时,能返回一杯豆浆(制造出的对象)

但豆浆机本身也是一台机器,也是一个对象

豆浆机身上也有属性–如开关,进水口等

function Hashiqi(){
this.bark = function(){
alert('wuwu');
}
}

Hashiqi.ajax = function(){//ajax是Hashiqi的静态方法
alert('ajax');
}
var h = new Hashiqi();//这个对象里面没有ajax方法


*ajax方法是属于函数本身的,和返回的对象没有关系

*bark的调用必须new Hashiqi得到对象,且由返回对象才能调用

*ajax方法要调用,不需要new对象,直接用Hashi器来调用

我们之前有没有接触过静态方法?

1.Math.random();静态方法

2..ajax();静态方法3.写jquery方法2中方法通过闭包把方法写到jquery上的原型上直接增加对象的静态方法

.ajax//调用函数本身的().ajax//调用对象的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: