js 一些基础知识
数据类型:
作用域
每个函数都有自己的执行环境,执行环境定义了变量有权访问的其他数据,决定了他们各自的行为。
每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量或函数都保存在这个对象中。
当代码在一个环境中执行时,会创建变量对象的作用域链
js没有块级作用域
函数声明与函数表达式
function test(){}//函数声明,他的重要特性是函数声明提升
var test=function(){}//函数表达式
递归
保险的递归写法(命名函数表达式):
1 var factorial = (function fa(num){ 2 if(num<=1){ 3 return 1; 4 }else{ 5 console.log(num); 6 return num*fa(num-1); 7 } 8 });
闭包
创建闭包:在一个函数内部创建另一个函数;
作用:延长变量的作用域链
原理:内部函数的作用域链包含外部函数的作用域链
缺点:过度使用可能会造成内存泄露
例子:这个例子中写了两个按钮,点击按钮的时候弹出此按钮被点击的次数。
1 <body> 2 <button id="btn1" onclick="test1()">btn1</button> 3 <button id="btn2" onclick="test2()">btn2</button> 4 <script> 5 var test1 = showClickNumber(); 6 var test2 = showClickNumber(); 7 function showClickNumber(){ 8 var number = 0; 9 return function(){ 10 number = number+1; 11 alert(number); 12 } 13 } 14 </script> 15 </body>
这个例子可以形象地描述一个闭包:showClickNumber函数内部先定义了一个变量number用于计数,然后返回一个匿名函数;
在这个匿名函数里面,我们使用到了外部函数的number变量;
这样虽然showClickNumber函数执行完了,但它的内部变量number也不会销毁,因为他还在被test1,test2方法引用。
虽然只申明了一个变量,两个按钮却会各自统计各自的点击数量,不会相互影响
关于this对象
this对象是在运行时基于函数的执行环境绑定的
1、在全局函数中:this=window;
2、函数作为某个对象的方法被调用时:this=对象;
3、通过call()或apply()改变函数执行环境时,this指向指定的对象
模仿块级作用域--私有作用域
(function(){ //块级作用域 })();
js没有块级作用域的概念,用这样一个自执行的函数(闭包)包起来,它里面的变量就成了局部变量,还可以提高运行速度
创建对象的推荐方式
1、组合使用原型模式和构造函数模式
function Persion(name,age,job){ this.name = name; this.job = job; this.age = age; } //protocol指向函数的原型对象,原型对象会自动获得constructor(构造函数)属性 //constructor包含一个指向prototype属性所在函数的指针 //通过constructor,还可以为原型对象添加其他属性和方法 //下面的代码,我们重置了Persion原型,应该为constructor赋值,否则就丢失了constructor值 Persion.prototype={ constructor:Persion, sayName:function(){ alert(this.name); } }
2、动态原型模式
1 function Persion(name,age,job){ 2 this.name = name; 3 this.job = job; 4 this.age = age; 5 if(typeof this.sayName() != "function"){ 6 Persion.prototype.sayName = function(){ 7 alert(this.name); 8 } 9 } 10 }