一、new function的用法
1.用法一
此种用法的跟使用{}的区别是:它比较灵活,可以在内部定义变量、函数等
var obj = new function(){
var a = 1;
var b = 2;
this.total = a + b;
return a + b; // 被忽略
}
相当于:
var obj = {
total : 3
}
2.用法二
此种用法就是闭包而已
var test = new function(){
var a = 1;
var b = 2;
return function(c){
return a + b + c;
}
}
test(3);//6
相当于:
var test = (function(){
var a = 1;
var b = 2;
return function(c){
return a + b + c;
}
})();
test(3);//6
二、Function.prototype.apply.call的用法
function log(){
if(window.console){
// 第一个参数是apply要执行的函数,第二个参数为context,第三个参数为要执行函数的参数列表
Function.prototype.apply.call(console.log,console,arguments);
// Function.apply.call(console.log,console,arguments); // 也是可以的。
}
}
三、构造函数中return
1.构造函数return基本类型的值
function Person(){
var a = 2;
this.a = a;
return a;
}
var p = new Person();
console.dir(p); // 此时p的值并不是2,而是一个有一个属性a其值为2的对象
2.构造函数return Object类型的值
function Person(){
var a = 2
return {
name:"李彦峰",
a : a
}
}
var p = new Person();
console.dir(p); // 此时p为一个对象 {name:"李彦峰",a:2}
结论:
-
在构造器中
return
,如果是基本类型的值,那么使用new
操作符将会按照预期,返回一个对象,就相当于构造函数中的return
语句不存在一样 - 在构造器中如果
return
的是一个Object类型(function/基本类型的包装类型/Object类型),那么new
操作符就相当于不存在一样,也就是说,js引擎会把return
出去的引用值作为变量,而不会把new
出来的新对象的引用赋值给相应的变量。。
四、函数的属性
- 函数的属性列表
- arguments
- caller
- length
- name
- prototype(这个属性先略过)
上述的属性都可以通过 函数名.属性
来引用,length
是形参的个数。如果是函数表达式的话,name
是空串。
function outer(a,b,c){
console.log(outer.arguments); // [1,2,3,4]
console.log(outer.caller); // null
console.log(outer.length); // 3
console.log(outer.name); // outer
function inner(){
console.log(inner.arguments); // []
console.log(inner.caller); // 打印出整个函数体
console.log(inner.length); // 0
console.log(inner.name); // inner
// 内部函数访问外部函数的属性
console.log(arguments.callee.caller.arguments); // [1,2,3,4]
// console.log(inner.caller.arguments); // [1,2,3,4]
console.log(arguments.callee.caller.caller); // null
// console.log(inner.caller.caller); // null
console.log(arguments.callee.caller.length); // 3
// console.log(inner.caller.length); // 3
console.log(arguments.callee.caller.name); // outer
// console.log(inner.caller.name); // outer
}
inner();
}
outer(1,2,3,4);
五、局部变量
对于局部声明的重复变量,只有第一个声明有效,也就是说,js引擎会忽略除了第一个之外的所有的声明
// 第一种
function test(){
var name = "李彦峰";
var name;
console.log(name); // 李彦峰
}
// 第二种
function test(){
var name;
var name = "李彦峰";
console.log(name); // 李彦峰
}
注意:第二种好像不符合 对于局部声明的重复变量,只有第一个声明有效的说法,其实也是符合的,因为js引擎会对函数进行2轮处理,局部变量的声明在第1轮处理(变量声明提升),所以第1轮会保证只有一个name被声明,第2轮才进行局部变量的初始化(代码执行到赋值语句才进行初始化),即会把第1轮声明的局部变量赋值。。
严格模式下不能通过
函数名.arguments
的方式访问arguments
对象,不能访问caller
属性
六、arguments
arguments
对象拥有一个callee
属性,该属性是一个指针,指向拥有这个arguments
对象的函数
arguments
对象内部属性值是跟参数一一对应的,改变其中一个的值都会影响另外一个。
看代码:
function test(a,b,c){
console.log(arguments); // [1,2,4]
a = 8;
console.log(arguments); // [8,2,4]
arguments[1] = 909;
console.log(b); // 909
console.log(arguments); // [8,909,4]
}
test(1,2,4);
注意:严格模式下不能访问
arguments
对象的callee
属性
原文参见[Github]