Javascript的一些坑点(二)
1、this指向问题
当我们需要抽离一个类/对象的函数出来使用时,需要手动调整函数内部的this指向
如:
class Foo {
constructor(num) {
this.num = num;
}
getNum() {
return this.num;
}
}
let obj = new Foo();
print(obj.getNum);
function print(fn) {
Promise.resolve()
.then(function() {
fn();
resovle();
})
.then(function() {
...
})
}
如果按这么写的话,将会得到一个报错:UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'num' of undefined
, 究其原因,是将 getNum 从对象/类原型函数中抽离出来,此时处在的作用域为 全局, this下无num这是其一,this为undefined是因为node默认采用的严格模式。
因此,改正过来的话 只需要 fn.call(obj)
即可
或者使用闭包进行改造
class Foo {
...
getNum() {
let context = this;
return function() {
return context.num;
}
}
}
2、过度使用箭头函数
使用箭头函数的好处就是节省篇幅,代码看起来很简短,在处理简单的逻辑时效率会很高,如 创建一个矩阵,给一个数组设置排序规则等等
// 创建m*n的矩阵
let arr = new Array(m).fill(0).map(v=>new Array(n).fill(0));
// 将nums按升序规则原地稳定排序
nums.sort((a,b) => a-b);
但是逻辑一旦复杂起来时,用箭头函数写出的代码可阅读性极差,让人难以费解,甚至还需要数括号来判断嵌套关系,如:
/*
const N = 5;
let obj = new Scheduler(N);
const timeout = ms => new Promise(res => setTimeout(res, ms));
const LOG = console.log;
*/
const addTask = obj.add((time, order) => timeout(time)).then(() => LOG(order));
以上为被注释的代码令人费解,大致逻辑是 then被add返回的Promise调用,但看的不仔细的话甚至会认为 then 是被 timeout(time) 返回的Promise调用的。
因此,避免这个坑的办法是 箭头函数超过1层嵌套时,就用函数声明把:
function addTask(time, order) {
obj.add(function task(time, order) {
timeout(time);
}).then(function() {
LOG(order);
});
}
但是箭头函数与声明式函数function应该是不能随意来回切换写法,因为箭头函数相较声明式函数function来说,有以下几点区别,为了简便描述,将箭头函数记作 arrow,将声明式函数记为 fn
(1)fn中this指向为调用它的环境,arrow的this指向固定为创建它的环境,call/apply/bind都无法改变
(2)arrow不可用作构造函数,因此无 new.target
(3)arrow无arguments属性,只可用 …params 得到参数列表 params
(4)无原型,无super
因此,应该在合适的环境中使用箭头函数
上一篇: 记录使用javascript中的一些坑
下一篇: sass的一些坑,一些规范
推荐阅读
-
------ 开源软件 Tor(洋葱路由器,构建匿名网络的方案之一)源码分析——主程序入口点(二)------
-
PHP 类的一些知识点_PHP教程
-
为什么有一些二分查找取 mid 的时候要加 1
-
JavaScript比较冷门的知识点
-
一些常用的JS功能函数代码_javascript技巧
-
制作网页过程中可以参考的一些JAVASCRIPT技术
-
jQuery实现checkbox即点即改批量删除及中间遇到的坑
-
js 弹出框只弹一次(二次修改之后的)_javascript技巧
-
林大妈的JavaScript基础知识(二):编写JavaScript代码前的一些简单工作
-
jscript读写二进制文件的方法_javascript技巧