阅读《JavaScript面向对象编程指南(第2版)》 -- 第三章
笔记
函数的声明
- 关键字function
- 函数名称
- 函数所需的参数
- 函数要执行的代码块
- return 子句 一个函数只有一个返回值
参数
- arguments变量返回函数所接收的所有参数
- arguments.length返回函数调用时所接收的所有参数数量
- arguments是类数组
预定义函数
- parseInt() 转为整数,失败NaN,第二参数(10|16|8)进制,遇到第一个异常字符就放弃。
- parseFloat() 转为浮点数,遇到第一个异常字符就放弃,支持指数
- isNaN() 是否可以转为数字
- isFinite() 是否是一个非Infinity也非NaN的数字
- encodeURI() 转义完整url(识别http://)
- decodeURI() 反转义完整url(识别http://)
- edcodeURIComponent() 转义部分url(不识别http://)
- decodeURIComponent() 反转义部分url(不识别http://)
- eval() 将输入的字符串当做JavaScript代码来执行 JavaScript中最大的数字为1e+308,最小数字是5e-324
变量作用域
- 变量的定义是以函数为作用域的。
- 全局作用域是指定义在所有函数之外的变量。
- 局部作用域是指定义在某个函数中的变量。
- 声明时没有var,默认为全局变量。
变量提升
- 函数局部作用域会覆盖全局作用域。
- JavaScript在执行函数时,所有变量声明(函数)都会被提升到最先执行,赋值操作不会提升。
- 将函数赋值给变量,称之为函数表达式。
- 函数表达式不会提升,函数声明会提升,函数声明可以在声明之前调用函数。
回调/即时/私有/重写自己的函数
-
将函数A传递给函数B,并有函数B来执行函数A。A就是回调函数。
-
将匿名函数放进一对括号中,然后外面在紧跟一对括号,称即时函数。第二对括号起立即调用的作用。适合执行一些一次性的初始化任务。
(function(name) {...}) ('lili') || (function(name) {...} ('lili') )
-
在函数内部声明和调用的函数为私有函数。
-
函数在第一次调用后重写自己,从而避免了每次调用时一些不必要的操作,适用于执行某些初始化工作。让函数根据浏览器重新定义自己。
function a(){
... // 初始化
return function (){
...
}
}
a = a()
function a(){
... // 初始化
a = function (){
...
}
}
闭包
- 在函数内部定义的所有变量在该函数外部是不可见的。
- 有权访问另一个函数作用域中的变量的函数,称为闭包。或者一个函数在其父极函数返回之后留住对父极作用域的链接。
- 函数所绑定的是作用域本身,而不是函数定义时的值。
// 闭包1 返回函数,赋值全局变量
function F() {
var b = 'local variable'
var N = function(){
return b;
}
return N
}
var inner = F()
inner() // 'local variable'
// 闭包2 无需返回,内部赋值全局变量
var inner;
function F() {
var b = 'local variable'
var N = function(){
return b;
}
inner = N
}
inner() // 'local variable'
// 闭包3 返回函数,使用函数参数
function F(param) {
var N = function(){
return param;
}
param++;
return N
}
var inner = F(123)
inner() // 124
- 在循环中,创建闭包时,不会记录变量的值,拥有的只是相对域的一个链接。
function F(){
var arr = [];
for(var i=0;i<3;i++){
arr[i] = function(){
return i;
}
}
return arr
}
var arr = F()
arr[0]() // 3
arr[1]() // 3
arr[2]() // 3
function F(){
var arr = [];
for(var i=0;i<3;i++){
arr[i] = (function(x){
return function(){
return x;
}
})(i)
}
return arr
}
var arr = F()
arr[0]() // 0
arr[1]() // 1
arr[2]() // 2
getter and setter
- 闭包的应用
- 假设有一个变量,它所表示某类特定的值或区间,不想暴露给外部,不想其他代码有修改的变量值得可能,所以要将它保留在相关函数内部。然后提供了两个额外的函数。一个用于获取变量的值。另一个用于给变量重新复制。并在函数中引入某种验证措施,以便赋值前给与一定的变量保护。
var get,set ;
(function(){
var value = 0;
get = function(){
return value
}
set = function(newVal){
... // 验证
value = newVal
}
})()
迭代器
- 闭包的应用
- 通常我们都知道如何遍历简单的数组,但有时我们需要面对更复杂的数据结构,它们通常会有着数组截然不同的序列规则,这时候需要将“谁是下一个”的复杂逻辑封装成易于使用的next()函数,然后我们只需简单的调用next()就能实现相关的遍历操作了。
function setup(arr){
var i = 0;
return function(){
return arr[i++]
}
}
var next = setup(['a','b','c','d'])
next() // 'a'
next() // 'b'
next() // 'c'
next() // 'd'
练习题
function getRGB(color){
var colorArr = color.split('')
var one = parseInt((colorArr[1]+ colorArr[2]),16)
var two = parseInt((colorArr[3]+ colorArr[4]),16)
var three = parseInt((colorArr[5]+ colorArr[6]),16)
return `rgb(${one},${two},${three})`
}
function getRGB(color){
var arr=[];
var colorArr = color.split('')
for(var i=1;i<colorArr.length;i=i+2){
arr.push(parseInt((colorArr[i]+ colorArr[i+1]),16))
}
return 'rgb('+arr[0]+','+arr[1]+','+arr[2]+')'
}
var a = getRGB('#00FF00')
a //rgb(0,255,0)
// 2. 求值
parseInt(1e1) // 10 不支持指数为负数 (1e-1)
parseInt('1e1') // 1
parseFloat('1e1') // 10 指数为负数 (1e-1)0.1
// 3. alert的内容是什么
var a = 1;
function f(){
function n(){
alert(a)
}
var a = 2;
n()
}
f() // alert(2)