第十章-函数(下)-js红宝书笔记

1. 函数内部

函数内部存在两个特殊的对象:arguments 和 this。ES6新增了new.target 属性。

1.1 arguments

一个类数组对象,包含调用函数时传入的所有参数。
之前已经多次提到,arguments对象还有一个 callee 属性,是一个指向 arguments 对象所在函数的指针。

function factorial(num) { 
 if (num <= 1) { 
 return 1; 
 } else { 
 return num * arguments.callee(num - 1); 
 } 
}

上面代码中的arguments.callee可以代替函数名factorial实现递归。

1.2 this

1.2.1 在标准函数中,this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 this 值。

window.color = 'red'; 
let o = { 
 color: 'blue' 
}; 
function sayColor() { 
 console.log(this.color); 
} 
sayColor(); // 'red' 
o.sayColor = sayColor; 
o.sayColor(); // 'blue'

1.2.2 在箭头函数中,this引用的是定义箭头函数的上下文

window.color = 'red'; 
let o = { 
 color: 'blue' 
}; 
let sayColor = () => console.log(this.color); 
sayColor(); // 'red' 
o.sayColor = sayColor; 
o.sayColor(); // 'red'

将回调函数写成箭头函数可以避免一些问题。
避免this指向的不是想要的对象。

function King() { 
 this.royaltyName = 'Henry'; 
 // this 引用 King 的实例
 setTimeout(() => console.log(this.royaltyName), 1000); 
}
function Queen() { 
 this.royaltyName = 'Elizabeth'; 
 // this 引用 window 对象
 setTimeout(function() { console.log(this.royaltyName); }, 1000); 
} 
new King(); // Henry 
new Queen(); // undefined

1.3 caller

这个属性引用的是调用当前函数的函数
如果是在全局作用域中调用的则为 null。

function outer() { 
 inner(); 
} 
function inner() { 
 console.log(inner.caller); 
} 
outer();

以上代码会显示 outer()函数的源代码。
降低耦合度可以用arguments.callee.caller

function outer() { 
 inner(); 
} 
function inner() { 
 console.log(arguments.callee.caller); 
} 
outer();

在严格模式下访问 arguments.callee 会报错

new.target

ES中的函数始终可以作为构造函数实例化一个新对象,也可以作为普通函数被调用。
new.target是为了区分到底使用哪种方式调用的

function King() { 
 if (!new.target) { 
 throw 'King must be instantiated using "new"' 
 } 
 console.log('King instantiated using "new"'); 
} 
new King(); // King instantiated using "new" 
King(); // Error: King must be instantiated using "new"

2.函数属性与方法

两个属性:length和 prototype
两个方法:apply()和 call()。

2.1 函数的length属性

length 属性保存函数定义的命名参数的个数

function sayName(name) { 
 console.log(name); 
} 
function sum(num1, num2) { 
 return num1 + num2; 
} 
function sayHi() { 
 console.log("hi"); 
} 
console.log(sayName.length); // 1 
console.log(sum.length); // 2 
console.log(sayHi.length); // 0

2.2 函数的prototype属性

prototype 是保存引用类型所有实例方法的地方,这意味着 toString()、valueOf()等方法实际上都保存在 prototype 上。
相关内容已经在第 8 章详细介绍。

2.3 apply()方法和 call()方法

主要作用是传入函数体内 this值的能力。
apply()方法接收两个参数:

  • 函数内 this 的值。
  • 第二个参数可以是 Array 的实例,但也可以是 arguments 对象。
    call()方法和apply()方法差不多,只是把数组的接收变成了一个个分散开的。
function sum(num1, num2) { 
 return num1 + num2; 
} 
function callSum(num1, num2) { 
 return sum.call(this, num1, num2); 
} 
console.log(callSum(10, 10)); // 20

下面这个例子可以看出这两个方法的用法

window.color = 'red'; 
let o = { 
 color: 'blue' 
}; 
function sayColor() { 
 console.log(this.color); 
} 
sayColor(); // red 
sayColor.call(this); // red 
sayColor.call(window); // red 
sayColor.call(o); // blue

闭包

单独开一章节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值