1. 参数默认值

  • 默认是undefined
  • 形参可以有默认值,形参、实参哪个有值取哪个ES6,默认值属于ES6的内容,打印出的是符合人性化的结果
  • 形参有默认值,形参、实参无法统一、无论实参传入有值还是undefined(代码表现)
function test(a = 1, b) {console.log(a, b)console.log(arguments[0]) // undefined
}
test(undefined, 1) // 1 1
function test(a = 1, b) {console.log(a, b)// 1 1console.log(arguments[0]) // undefineda = 8console.log(a) // 8console.log(arguments[0]) // undefined
}
test(undefined, 1)
function test(a, b) {console.log(a, b)// 2 1console.log(arguments[0]) // 2a = 8console.log(a) // 8console.log(arguments[0]) // 8
}
test(2, 1)
function test(a, b) {a = 3;console.log(a)  // 3console.log(arguments[0]) // 3
}
test(1, 2)
function test(a = undefined, b) {console.log(a, b)
}
test(1, 1) // 1 1
// 用es5的写法设置默认值
function test(a, b) {a = arguments[0] || 1console.log(a, b) // 1 1
}
test(undefined, 1)
// typeof的方式
function test(a, b) {a = typeof (arguments[0]) === 'undefined'? 1: arguments[0]console.log(a, b)
}
test(undefined, 1) // 1 1

2. 预编译

  1. 检查通篇的语法错误
  2. 预编译的语法错误
  3. 解释一行,执行一行
  • 函数声明,函数整体提升
  • 变量声明,只有声明提升,赋值不提升

预编译的流程(函数执行前的步骤)

一、 函数内部

变量优先

  1. 创建AO对象:寻找函数里的形参和变量声明提升,添加到AO(活跃对象/函数上下文 activation object)里
  2. 把实参的值赋值给形参
  3. 寻找函数声明,添加到AO
  4. 执行函数(按函数语句走)// 执行时,对于前几步处理过的变量声明、函数声明将跳过
  5. 对于变量重复声明,红宝书的例子(js从来不会告诉你是否多次声明了同一个变量,遇到这种情况,它只会对后续的声明视而不见),不过它执行后续声明中的变量初始化
    =注意-==
function countFn(count) {for (var i = 0; i < count; i++) {console.log(i) // 0 1 2 3 4}var i // 重复 视而不见console.log(i) // 5
}
countFn(5)
function test(a) { // 预编译第一步,将形参添加到AO时var avar aconsole.log(a)  // 1
}
test(1)
// 打印
// f a(){}
// 1
// 1
// f (){}
function test(a) {console.log(a) // fn avar a = 1;console.log(a) // 1function a() { }console.log(a) // 1var b = function () { }console.log(b) // fn function d() { }
}
test(2)
function test(a, b) {console.log(a) // 1c = 0console.log(c) // 0var ca = 5console.log(a) // 5console.log(b) // f b(){}b = 6console.log(b) // 6function b() { }console.log(d) // f d(){}function d() { }console.log(b) // 6console.log(d) // f d(){}
}
test(1)
AO = {a:undefined → 1 → 5,b:undefined → f b → 6,c:undefined → 0,d: f d
}

二、全局

  1. 在通篇js执行前,创建GO(global object)全局上下文(即window)
  2. 寻找变量声明
  3. 寻找函数声明
  4. 执行(不要忘记赋值、注意执行顺序)
  • 函数表达式显然是报错,GO里test是变量undefined
test()
var test = function () { }
function test2(){}
GO = {test:undefined → f test(){}test2: f test2(){}
}
// 打印
// f a(){}
// undefiendGO = {b:undefineda:fa
}


console.log(b) // undefined
var b = 3;
console.log(b) // 3
console.log(a) // f a(a)
function a(a) {console.log(a) // f a()a() // undefined 5var a = 2;console.log(a) // 2function a() {console.log(b)var b = 5;console.log(b)}
}
a(1)
GO = {b:undefineda:fa(a)
}
AO = {a:undefined → 1 → fa() → 2b:undefined →
}

  • 不要混淆:AO内有a,不会再去查找GO里的a
  • 预编译不管if语句的,只要有变量声明就要放入AO
  • js中无块级作用域,即使用{}括起来,b也是声明在函数test内部的局部变量,会被添加到执行环境
  • 使用var声明的变量会被自动添加到最接近的环境中
function test() {return a;a = 1;function a() {};var a = 2
}
console.log(test()) // f a(){}AO = {a:undefined  → fa
}
function test() {a = 1;function a() { };var a = 2return a
}
console.log(test()) // 2
function test(e) {function e() { }console.log(e); // f e(){}arguments[0] = 2;console.log(e); // 2if (a) {var b = 3}var c;console.log(a); // undefineda = 4;var a;console.log(b); // undefinedf = 5;console.log(c); // undefinedconsole.log(a); // 4
}
var a
test(1)
console.log(f); // 5GO = {a: undefined test: f test(e){...},f: 5 // 在执行test内函数值
}
// 执行test(1)时创建AO
AO = {e:undefined  → 1 → f e(){} → 2 b: undefined  → c: undefined  → a: undefined → 4
}

暗示全局变量

  • 未用var 声明的b就是暗示全局变量,是window的属性之一
function test() {var a = b = 1
// 1. var a
// 2. b = 1 (赋值,没有在function内部声明,是全局变量,存到window)
// 3. a = b (赋值)
}


练习

var a = false + 1;
console.log(a) // 1 隐式类型转换
var b = false == 1;
console.log(b) // false

注意运算符优先级&&低于+
运算符优先级

if (typeof (a) && (-true) + (+undefined) + '') {console.log('通过了')  // 通过了} else {console.log('没通过')
}

if (1 + 5 * '3' === 16) {console.log('通过了') // 通过了
} else {console.log('没通过')
}

console.log(!!" " + !!'' - !!false || '没通过') // 1

ES5-5 参数默认值、递归、预编译、暗示全局变量相关推荐

  1. ES6: 参数默认值及中间域

    下午看了一章 ECMA-262 by Dmitry Soshnikov, 现在稍稍来小结下ES6中的参数默认值以及由此产生的参数中间作用域. 原文地址: http://dmitrysoshnikov. ...

  2. C++之函数参数默认值

    C++之函数参数默认值 1.参数默认值的指定方式 在 C++ 中,可以在函数声明时为参数提供一个默认值.这样在函数调用时,如果没有提供函数参数值,则使用默认值. e.g. 在函数声明时,指定参数默认值 ...

  3. C++ 笔记(13)— 函数(函数声明、函数定义、函数调用[传值、指针、引用]、函数参数默认值、函数重载)

    每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数. 1. 函数声明 函数声明告诉编译器函数的名称.返回类型和参数.函数声明包括以下几个部分: ret ...

  4. JavaScript中实现函数重载和参数默认值

    2019独角兽企业重金招聘Python工程师标准>>> 参数默认值是指在调用函数时,若省略了某个实参,函数会自动为该参数分配一个默认值,使得函数调用的方便性和灵活性大大提高. 举个例 ...

  5. 【Shell】设置变量默认值,参数默认值, 自动赋值

    设置变量默认值,参数默认值, 自动赋值 转自:https://zhuanlan.zhihu.com/p/98636736 默认参数(变量默认值) if 繁琐方式 if [ ! $1 ]; then$1 ...

  6. ES6新特性之函数优化-参数默认值

    函数优化 在ES6中,对函数的操作做了优化,使得我们在操作函数时更加的便捷. 函数参数默认值 在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法: function add(a , b) ...

  7. ES6——函数参数默认值

    ES6 之前,不能直接为函数的参数指定默认值,ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面. function fun(x = 'Hello'){console.log(x); } f ...

  8. ES6函数参数的解构赋值,以及2种设置参数默认值方法的区别

    文章目录 1. 函数参数的解构赋值方式 2. 函数参数解构设置参数默认值 1. 方法1 2. 方法2 3. 总结 1. 函数参数的解构赋值方式 下面代码中,函数add的参数表面上是一个数组,但在传入参 ...

  9. ES6:Rest 参数和参数默认值【转】

    Rest 参数 通常,我们需要创建一个可变参数的函数,可变参数是指函数可以接受任意数量的参数.例如,String.prototype.concat 可以接受任何数量的字符串作为参数.使用 Rest 参 ...

最新文章

  1. svn中的ignore
  2. html5字体颜色自动转换,【转】js里alert里的字体颜色怎么设置:字体颜色方法;fontcolor(color)...
  3. 8天学通MongoDB——第三天 细说高级操作
  4. java int == integer_java int与integer的区别
  5. 最优化——线性规划总结1(线性规划标准型,规范型,顶点)
  6. PHP Class中public,private,protected,static的区别
  7. linux 丢包多少正常_Linux 问题故障定位,看看这篇
  8. c ++查找字符串_C ++类和对象| 查找输出程序| 套装3
  9. 操作系统之内存管理:4、基本地址变换机构(段氏、页式、段页式)
  10. Timeline的Animation Track详解
  11. web前端前景近几年怎么样,是否饱和?
  12. vista中安装语言包出错解决
  13. 苹果手机屏幕助手_同时适用于安卓和苹果的手机助手工具--Anvsoft Syncios
  14. 安徽理工大学计算机设计大赛,安徽理工大学学子在2020年中国大学生计算机设计大赛中喜获佳绩...
  15. 学习笔记(01):Java小白修炼手册-工欲善其事必先利其器,掌握Java开发工具
  16. 如何正确安装和设置IBM Lotus Notes 邮箱客户端
  17. android cad插件下载,CAD看图大师下载
  18. SQL*Plus 系统变量之59 - VER[IFY]
  19. 硬笔书法“案”字怎样书写正确?“最美中国字”来教你!
  20. 今日学习在线编程题:幻数

热门文章

  1. keil中断函数的写法_在 KeilC里,中断子程序与函数有何不同?( )_学小易找答案
  2. java connection 共享_java 使用HttpURLConnection发送数据简单实例
  3. python函数增强代码可读性_写Python必须知道的这几个代码技巧!你会吗?
  4. 服务器是什么系统_服务器自愈路由系统、单线以及BGP多线的区别是什么?
  5. vue-router的hash模式和history模式,
  6. 小程序WXML基本使用
  7. Jsp+Servlet+MYSQL注册登录案例(界面难看,ε=(´ο`*)))唉)
  8. 1625 数字金字塔
  9. 酒鬼随机漫步(一个矢量类)
  10. CentOS工作内容(七)禁用IPV6