NoteDeep

函数的参数

js函数其实不在意你传递多少个参数,解析器永远不会有怨言。参数在内部是用一个arguments数组来表示的。

function howManyArgs(){
alert(arguments.length);
}
howManyArgs(1, 2); // 2
howManyArgs(); // 0
howManyArgs(1); // 1

参数传递:
function setName(obj) {
obj.name = 'a';
obj = new Object(); //重写obj
obj.name = "b";
}
var person = new Object();
setName(person);
console.log(person); // {name: "a"}
console.log(obj); // {name: "b"}


上面的例子,当在函数内部重写obj时,这个变量引用的就是一个新的对象了。 由于没有用var关键字,obj也变成了一个全局变量。

执行环节以及作用域

每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
变量对象有 “作用域链”

var a = 'a';
function b() {
var b='b';
function c() {
var c='c';
// 这里可以访问 a、b、c
}
// 这里可以访问 a、b
}
// 这里只能访问 a

函数的参数也被当做变量来对待。


Bind
window.color='red';
var o = {color:"blue"};
function sayColor(){
alert(this.color);
}
var objSayColor = sayColor.bind(o);
objSayColor(); // blue

给函数绑定一个this


递归和函数名解耦

//例子:阶乘
function factorial(){
if(num<=1){
return 1;
} else {
return num * arguments.callee(num-1); // 等同于 num * factorial(num-1)
}
}
这样递归就不依赖函数名称了。

通过函数表达式模仿块级作用域

function cntNum(cnt) { (function () { for(var i=0; i<cnt; i++) { console.log(i); } })() console.log(i); // 报错 }
当然,es6有let之后,就不需要这么麻烦了。

私有变量

任何在函数中定义的变量,都可以看成是私有变量。因为无法在函数外部访问,包括参数、局部变量、在函数内部定义的其他函数。

function Person(name) {
this.getName = function () { console.log(name); }
this.setName = function (val) { name = val; }
}
var person1 = new Person("a"); var person2 = new Person("b"); person2.setName('c'); person1.getName(); // a person2.getName(); // c
每个对象都私有的变量,实例之间不会互相影响。
因为函数的参数是一个局部变量(私有变量)。每一次调用函数或者new,局部变量name都会在内存中生成一次。

可以想象一下,连续调用多次函数,他们之间的参数肯定是独立的,不能共用的。
一般而言,当函数执行完后,这个临时生成的参数name变量就会被销毁,但是对于new而言却不会

new实际上会经历下面四个步骤
  • 创建一个新对象
  • 将构造函数的作用域赋给新对象
  • 执行构造函数中的代码(为这个对象添加属性)
  • 返回新对象(在构造函数本身没有return时,默认如此)
当构造函数的作用域赋给新对象时,不仅仅this被赋予了,生成的新对象仍在引用着那些局部变量,所以不会name被立刻销毁,这里其实有些类似闭包了。

静态私有变量

(function () { var name = ''; Person = function (val) { name = val; }; Person.prototype.getName = function () { console.log(name); }; Person.prototype.setName = function (val) { name = val; }; })(); var person1 = new Person("a"); var person2 = new Person("b");
person2.setName("c"); person1.getName(); // c person2.getName(); // c
所有实例间共享的变量,比如上例中的 name。一个实例变化,所有实例都一起变化。











评论列表

    函数的参数