JS函数的本质、作用域以及this和arguments

面试考点比较密集
参考阮一峰JavaScript函数

函数的五种声明方式

具名函数

var 声明一个变量,七种数据类型
function 声明一个函数,是个特例
不写return自动加上return undefined

 function f(x,y){
     return x+y
 }
 f.name // 'f'
image.png

关于console.log()

  1. console.log()返回undefined
  2. console.log()会在传入的参数里首先调用toString()方法
image.png
  1. 但是当打印到控制台的时候,没有写双引号,是chrome浏览器的原因
image.png

修改:比如可以在重写console.log()

image.png

匿名函数

 var f
 f = function(x,y){
     return x+y
 }
 f.name // 'f'

如果要声明匿名函数,就一定要把它赋给一个变量

image.png

var x = function y(){}

var f
 f = function f2(x,y){ return x+y }
 f.name // 'f2'
 console.log(f2) // undefined
image.png

直接声明function y(){} 与 var x = function y(){}的区别(和上面第二种匿名函数声明的区别):

image.png

然后刷新页面

image.png

直接报错,说y没有定义

区别:

image.png

第一种方式可以打印,第二种打印说不存在.
第一种整个外面的区域都可以访问y
第二种只有函数内部才可以访问到y.(可以访问的区域就是绿色圈起来的区域)

image.png

window.Function

window.Function

 var f = new Function('x','y','return x+y')
 f.name // "anonymous"

不常用

箭头函数

箭头函数都是匿名函数,没有名字,就像是匿名函数的简写形式

image.png
image.png

五种方式总结

image.png

函数的name属性

// 1具名函数
 function f(x,y){
     return x+y
 }
 f.name // 'f'
 
// 2匿名函数
 var f
 f = function(x,y){
     return x+y
 }
 f.name // 'f'
 
// 3具名函数赋值
 var f
 f = function f2(x,y){ return x+y }
 f.name // 'f2'
 console.log(f2) // undefined
 
// 4window.Function
 var f = new Function('x','y','return x+y')
 f.name // "anonymous"
 
// 5箭头函数
 var f = (x,y) => {
     return x+y
 }

f.name//"f"

函数的本质

函数就是一段可以反复调用的代码块。函数是可以执行一段代码的对象。
调用的英文单词call
函数在内存中为字符串

函数在内存中:

image.png

即函数也是一个对象,广义上

eval()函数

模拟函数本质

image.png

函数是一个对象,里面有参数,函数体,调用方法
f是函数,是对象,f.call()是一个执行函数体的方法

总结
js中有七种数据类型,

number string boolean null undefined symbol object

前六种是简单类型,object是前6种的各种组合,所以是复杂类型
原型链

image.png

函数的调用:f(1,2)与f.call(undefined,1,2)

f(1,2)是简单用法
f.call(undefined,1,2)才是真实的用法

image.png

用call 便于理解this,是硬核技术
call用法:

image.png

参数从第二个开始

this和arguments

this就是f.call()里面的第一个参数,在JAVA里面比较有用,在JS里没什么用。当初是为了像JAVA而设计的,在JS里面没什么用,this就是一个参数。

image.png

arguments是参数数组

image.png

this

了解这篇博文this 的值到底是什么?一次说清楚
特例:当call()的第一个参数是undefined的时候, this 是 window.

image.png
image.png

当启用严格模式的时候,call 里的第一个参数是什么,this 就是什么

image.png

this的作用先不说

arguments 是参数组成的伪数组

arguments是一个伪数组:里面有0123这些次序,也有length,长得像数组,但是.伪数组的__proto__没有指向的是 Array.prototype,或者说原型链中没有Array.prototype,即原型链中没有和Array.prototype有关的 ,也就是说只是一个像数组的对象而已.

image.png

没有 push

换句话说:
arguments是一个伪数组,伪数组的意思就是长得像数组,但是它的__proto__指向的不是Array.prototype,并且伪数组的整个原型链中都没有Array.prototype,即也使用不了a.push()之类数组特有的函数API(没有数组的公有属性)。arguments就是一个长得像数组的普通对象。

call stack 调用栈

每进入一个函数,就在栈里记录一个记号,当调用完之后return的时候,就跳到做的记号哪里,弹出栈里的记号

image.png

调用演示:
普通调用
嵌套调用
递归调用

Stack Overflow错误

堆栈溢出

image.png

超出call stack调用栈

segment fault也是一种错误,c语言里面的

作用域

作用域了解一下这篇JS里的作用域,变量提升与函数提升
什么情况下直接使用 a=1 会使a直接变成全局变量(window.a)?
当写a=1这个代码的时候,首先计算机会认为这是赋值,当发现当前作用域没有声明a的时候,就继续往上找,看看上一层的作用域有没有声明a,就这样,一直找到window层即全局作用域层,就直接给全局变量window自动声明一个a.
就近原则,哪一个scope离赋值最近,赋值的就是哪一个作用域

这个f4里面的a只能是他自己本身的作用域和他的父作用域,跟f1里面的a=2没有关系

image.png

f4打印出来的a是1

有函数就有作用域。
一定要变量提升,一开始看见题目就要变量提升。
浏览器在画作用域树的时候都是先找到所有变量声明,然后把这些声明都放到最前面。

image.png
image.png

闭包

闭包就是如果一个函数使用了它范围外(作用域)的变量,那么 【这个函数+这个变量】组合的整体 就叫做闭包。
了解这篇 JS 中的闭包是什么?

题目

  • 1.f1.name 是多少???
var f1 = function f2(){};

答:f2

  • 2.f2.name 是多少???
var f1 = function f2(){};

答:什么都不是

image.png
  • 3.打印出什么???
var f1 = function f2(){};
console.log(f2);

答:f2 is not defined(f2 不存在,而且 f2 不是 undefined)

  • 4.非严格模式下,打印出什么???
function f(){
    console.log(this)
}
f.call(1)

答:Number 对象 1
这里是说返回的是一个对象,类型为Number, 字面量的表示是1 不是字符串 number 1 因为数字、字符串 是特殊的对象, 是对象的字面量表示方法,所以数字才有属性。 console.log(this)的时候就把它强制还原为原始对象状态,就像 new Number(1)

image.png
  • 5.严格模式下,打印出什么???
function f(){
    'use strict'
    console.log(this)
}
f.call(1)

答:1

image.png
  • 6.下面的例子不带参数,打印出什么???
function f(){
    console.log(this)
}
f.call()

答:window

image.png
  • 7.严格模式下,不带参数,打印出什么???
function f(){
    'use strict'
    console.log(this)
}
f.call()

答:Undefined

image.png
  • 8.a的值是什么???
var a = console.log(1)

答:Undefined

  • 9.a 的值是什么???f
function f(){
    return 1
}
a = f

答: 函数 f

image.png
  • 10.a 的值是什么???f.call()
function f(){
    return 1
}
var a = f.call()

答: 1

  • 11.a的值是什么???
var a = 1,2 

答:报错
因为 = 和 , 都是运算符 但= 的优先级更高 逗号是最低的

image.png
  • 12.a 的值是什么???
var a = (1,2)

答:2

image.png
  • 13.a 的值是什么???
var a = (1, console.log(2))

答:Undefined,和上面 var a = console.log(1) 一样

  • 14.a 的值是什么???
function f(){
    return function f2(){}
}
var a = f.call()

答:函数f2

image.png
  • 15.b 的值是什么???
function f(){
    return function f2(){}
}
var a = f.call()
var b = a.call()

答:undefined 结合上面的看一下,a的值是f2,然后b的值 = f2.call() ???

image.png
  • 16.a 的值是什么???
function f(){
    return function f2(){}
}
var a = f.call().call()

答:和上一题一样的。

  • 17.打印出什么???
function f1(){
    console.log(this)
    function f2(){

    }
}
var obj = {name: 'obj'}
f1.call( obj )

答:对象obj,因为,这个就像上面的f1.call(1)结果就是 Number 对象 1 效果一样。

image.png
  • 18.打印出什么???
function f1(){
    function f2(){
        console.log(this)
    }
    f2.call()
}
var obj = {name: 'obj'}
f1.call( obj )

答: window 对象 这里面的f2.call()是不带参数的,所以这里面的this就是window对象。不理解的话就看看上面第6题,f.call()不带参数的情况下,打印出的结果。

image.png
  • 19.为什么两个 this 值不一样?
function f1(){
    console.log(this) // 第一个 this
    function f2(){
        console.log(this) // 第二个 this
    }
    f2.call()
}
var obj = {name: 'obj'}
f1.call( obj )

答:

  1. 每个函数都有自己的 this,为什么会一样?
  2. this 就是 call 的第一个参数,第一个 this 对应的 call 是 f1.call(obj),第二个 this 对应的 call 是 f2.call()
  3. this 和 arguments 都是参数,参数都要在函数执行(call)的时候才能确定
  4. 你以为名字一样值就一样吗?
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343