目录
究竟是怎么样的一道题,能让我拿出来说说呢?下面请看代码:
function fun(a, b) {
console.log(b);
return {
fun: function(c) {
return fun(c, a);
}
};
}
var d = fun(0);
d.fun(1);
d.fun(2);
d.fun(3);
var d1 = fun(0)
.fun(1)
.fun(2)
.fun(3);
var d2 = fun(0).fun(1);
d2.fun(2);
d2.fun(3);
function fun(a, b) {
console.log(b);
return {
fun: function(c) {
return fun(c, a);
}
};
}
var d = fun(0);
d.fun(1);
d.fun(2);
d.fun(3);
var d1 = fun(0)
.fun(1)
.fun(2)
.fun(3);
var d2 = fun(0).fun(1);
d2.fun(2);
d2.fun(3);
undefined
VM1036:2 0
VM1036:2 0
VM1036:2 0
VM1036:2 undefined
VM1036:2 0
VM1036:2 1
VM1036:2 2
VM1036:2 undefined
VM1036:2 0
VM1036:2 1
VM1036:2 1
{fun: ƒ}
//答案:
//undefined,0,0,0
//undefined,0,1,2
//undefined,0,1,1
JS 函数分两种:具名函数(命名函数)和匿名函数。
# 如何判断两种函数的方法呢?
可以用 fn.name (opens new window) 来判断,如果有 name 就是具名函数,如果没有 name 就是匿名函数。
需要注意的是在 IE 浏览器上无法获取具名函数的 name,会返回 undefined 的结果,而在谷歌浏览器上就可以获取。
// 获取名称
function getFunctionName(fun) {
if (fun.name !== undefined) return fun.name;
var funName = fun.toString();
funName = funName.substr('function '.length);
funName = funName.substr(0, funName.indexOf('('));
return funName;
}
2
# 函数创建的方法有哪些?
第一种是:声明函数,声明函数方法,包括函数名和函数体。
function funDa() {}
第二种是:创建匿名函数的表达式。
创建一个变量,这个变量的内容是一个函数,为匿名函数
var funDa = function() {};
这样这个函数就没有了 name
var funDa = function() {};
getFunctionName(funDa).length;
// 0
第三种是:创建具名函数表达式。
var funDa = function dada() {};
创建一个变量,变量赋值的内容为一个带有名称的函数。具名函数表达式的函数名只能在创建函数内部使用,函数的外层只能使用 funData,dada 函数名只能在创建函数内部使用。
在对象内定义函数,也是属于函数表达式。
第四种是:Function 构造函数
Function("alert(1)");
ƒ anonymous() {
alert(1)
}
Function("dada");
ƒ anonymous() {
dada
}
new Function("alert(1)");
ƒ anonymous() {
alert(1)
}
new Function("dada");
ƒ anonymous() {
dada
}
Function 构造函数传一个函数字符串,返回包含这个字符串命令的函数。
第五种是:自执行函数
( function(){
alert(1);
})();
undefined
( function(){
alert(1);
})
ƒ (){
alert(1);
}
(function da1() {
alert(1);
})();
自执行函数也是“函数表达式”。
第六种是:其他
运用 eval,setTimeout,setInterval 等方法。
3
第一个 fun 函数是属于标准的具名函数声明,是新创建的函数,返回的是一个对象字面量表达式,属性一个新的 Object。
这返回,对象内部包含一个 fun 的属性,属于匿名函数表达式,这个 fun 属性存放的是一个新创建匿名函数表达式,所有声明的匿名函数都是一个新函数。则第一个 fun 函数和第二个 fun 函数不同,都是新创建的函数。
4
函数作用域链的问题
对象内部的函数表达式:
var d = {
fn: function(){
console.log(fn);
}
};
d.fn();
VM1879:3 Uncaught ReferenceError: fn is not defined
at Object.fn (<anonymous>:3:21)
at <anonymous>:6:3
fn @ VM1879:3
(anonymous) @ VM1879:6
var d1 = {
fn: function(){
console.log("dada");
}
};
d1.fn();
VM1973:3 dada
undefined
非对象内部的函数表达式:
var da = function () {
console.log(da);
};
da();
VM2270:2 ƒ () {
console.log(da);
}
undefined
使用 var 可以访问到存放当前函数的变量,var da,da()访问函数的变量,在对象内部不能访问到。
5
函数作用域链:
function fun(a, b) {
console.log(b);
return {
fun: function(c) {
return fun(c, a);
}
};
}
var d = fun(0);
d.fun(1);
d.fun(2);
d.fun(3);
var d1 = fun(0)
.fun(1)
.fun(2)
.fun(3);
var d2 = fun(0).fun(1);
d2.fun(2);
d2.fun(3);
var d = fun(0);
d.fun(1);
d.fun(2);
d.fun(3);
undefined
VM2273:2 0
VM2273:2 0
VM2273:2 0
第一个 fun(0)在调用第一层 fun 函数,第二个 fun(1)是在调用前一个 fun 的返回值的 fun 函数。即就是 fun(1),fun(2),fun(3)函数独使在调用第二层 fun 函数,第一次调用 fun(0)时,b 为 undefined,第二次调用 fun(1),c 为 1,a 为 0。
var d = fun(0);调用的是第一层
而 d.fun->fun(0).fun 调用第二层
fun:function(1),return fun(1,a),fun(1,0),此时 fun 闭包了外层函数的 a,也就是第一次调用的 a=0。这样子第一层 fun 函数为 fun(1,0),所以为 0。
第一次:
function fun(0,undefined) {
console.log(undefined)
return {
fun: function(c) {
return fun(c,0);
}
};
}
fun(0),b 为 undefined,fun(0).fun(1),c=1,此时 fun 闭包外层函数的 a,也就是第一次调用的 a=0,即 c=1,a=0,并在内部调用第一层 fun 函数 fun(1,0),所以 b=0。
function fun(a,b) {
console.log(b)
return {
fun: function(1) {
return fun(1,0);
}
};
}
第三次调用 fun(2)时,c 为 2,还是调用 d.fun,还是闭包了第一次调用时的 a,fun(2,0)所以输出 b 为 0。
function fun(a, b) {
console.log(b);
return {
fun: function(c) {
return fun(c, a);
}
};
}
var d = fun(0);
d.fun(1);
d.fun(2);
d.fun(3);
6
var d1 = fun(0)
.fun(1)
.fun(2)
.fun(3);
从 fun(0)调用第一层 fun 函数,返回值为一个对象,第二个 fun(1)调用的是第二层 fun 函数,后面的也是第二层 fun 函数。
第一层 fun(0),b 为 undefined,第二层.fun(1)时 c 为 1,c=1,a=0,内部调用第一层 fun 函数 fun(1,0),所以 b 为 0。
调用你.fun(2)时,c 为 2,此时当前的 fun 函数不是第一次执行的返回对象,而是第二次执行的返回对象,第二次执行第一层 fun 函数是:
fun(1,0),a=1,b=0。第三次执行 fun 函数,c=2,a=1
function fun(a,b) {
console.log(b)
return {
fun: function(1) {
return fun(1,0);
}
};
}
fun(1,0),a=1,b=0。第三次执行fun函数,c=2,a=1
function fun(a,b) {
console.log(b)
return {
fun: function(2) {
return fun(2,1);
}
};
}
// 1
function fun(2,1) a=2, b=1
第四次调用.fun(3)为 c 为 3
// a=2
function fun(a,b) {
console.log(b)
return {
fun: function(3) {
return fun(3,2);
}
};
}
7
var d2 = fun(0).fun(1);
d2.fun(2);
d2.fun(3);
var d2=fun(0).fun(1);
// undefined, 0
此时的return(c=1,a=0),return fun(1,0),所以b为0
d2.fun(2);
第三次调用.fun(2),c 为 2
// c为2,a=1,b=0
function fun(a,b) {
console.log(b)
return {
fun: function(2) {
return fun(2,a);
}
};
}
所以 return fun(2,1) function fun(a=2,b=1),所以为 1
d2.fun(3),c 为 3,还是调用的第二次的返回值,最终调用第一层的 fun(a,b)
// c为3,a=1,b=0
function fun(a,b) {
console.log(b)
return {
fun: function(3) {
return fun(3,a);
}
};
}
所以 return fun(3,1) function fun(a=3,b=1),所以为 1
注意这里的:
// c为3,a=1,b=0
这是调用这个代码的结果
(a = 1), (b = 0);
var d2 = fun(0).fun(1);
好了,这样就知道大概的答案和讲解了:
8
总的来说,你明白了!讲的好辛苦,给个赞哦!求奖励,我来了
function fun(a, b) {
console.log(b);
return {
fun: function(c) {
return fun(c, a);
}
};
}
var d = fun(0);
d.fun(1);
d.fun(2);
d.fun(3);
var d1 = fun(0)
.fun(1)
.fun(2)
.fun(3);
var d2 = fun(0).fun(1);
d2.fun(2);
d2.fun(3);
undefined
VM1036:2 0
VM1036:2 0
VM1036:2 0
VM1036:2 undefined
VM1036:2 0
VM1036:2 1
VM1036:2 2
VM1036:2 undefined
VM1036:2 0
VM1036:2 1
VM1036:2 1
[]
{fun: ƒ}