毫不夸张,你能看到这篇文章,是你的运气,里面都是干货,在理解js的道路上容易误解的和关键点的知识。牛逼先不吹….看内容
ES6 将箭头函数纳入标准,很多人都知道一些基本的特性,比如下面的:
理解箭头函数this指向只要记住箭头函数 this 的指向(不仅仅是this,其实super,new.target等)由外围最近一层非箭头函数决定
。当然这里面有些细节,什么叫最近一层非箭头函数
。
比如函数里包裹箭头函数
var Animal = function() {
this.name = "Animal";
this.speak = (words) => {
console.log(this.name + ' is saying ' + words + '.');
}
}
var cat = new Animal();
cat.speak("miao ~");
输出:Animal is saying miao ~.
。箭头函数里this指向的是函数本身。
再比如
var lastName = 'postbird';
const person = {
lastName:"ptbird",
getLastName:()=>{
console.log(this.lastName)
}
};
person.getLastName();
输出: postbird
.箭头函数this指向windows。
注意最近一层非箭头函数
。person本身是对象,不是函数,this指向person定义时的上下文环境,也就是window,同时lastName属于person的内部且与getLastName函数是等价的。
再比如下面的,箭头函数所在的非箭头函数在对象里。
var adder = {
base : 1,
add : function(a) {
var f = v => v + this.base;
return f(a);
},
};
console.log(adder.add(1));
输出 2
箭头函数在add方法里,add虽然定义在对象adder里,但箭头函数 this 的指向(不仅仅是this,其实super,new.target等)由外围最近一层非箭头函数决定
,所以箭头函数里this其实是adder.
总之,一般我们只会遇到在在函数里使用箭头函数和对象里使用箭头函数,3者情况见上面即可。
参考ES6对象方法声明时箭头函数this的指向
[非箭头函数this指向](this 指向详细解析(箭头函数))
它是js里的一个方法,reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
var test1 = function(){
console.log("方法一:test1");
}
var test2 = function(str){
console.log("方法二:test2" + str);
}
var test3 = function(str){
console.log("方法三:test3."+str);
return "方法三被执行"
}
var arr = [test1,test2, test3]
var all = arr.reduce(function(a,b){
return function(){
return a(b.apply(undefined, arguments))
}
})
all("ss");
结果
方法三:test3.ss
方法二:test2方法三被执行
方法一:test1
var numbers = [65, 44, 12, 4];
var total = numbers.reduce(function(a,b){
return a+b;
})
console.log(total);
结果125
reduce的语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
function compose() {
for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {
funcs[_key] = arguments[_key];
}
if (funcs.length === 0) {
return function (arg) {
return arg;
};
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce(function (a, b) {
return function () {
return a(b.apply(undefined, arguments));
};
});
}
使用方法
compose.apply(undefined, 数组)(参数);
var sum = (num1, num2) => num1 + num2
return
,否则返回undefined
var sum = (num1, num2) => { return num1 + num2 }
var sum = (n1, n2) => {
console.log(n1);
return n1 + n2
}
undefined
var sum = () => ({name: 'a'})
等同于
var sum = function sum() {
return { name: 'a' };
};
我发现js里行参和实参完全可以理解为2条并行的线,比如
function t1(){
console.log("打印参数: " + arguments.length);
return "t1";
}
console.log(t1("1"));
t1函数在定义时没有指明可接收参数,但我们依然可以传入参数,这个传入的参数就是实参,可以通过arguments
获取实参。
使用特殊对象 arguments
,开发者无需明确指出参数名,就能访问它们,用 arguments[0]
,即第一个参数的值(第一个参数位于位置 0,第二个参数位于位置 1,依此类推)。
arguments
和 parameters
经常被混为一谈,为了这个教程我们还是做一个2者的区分。在大多数标准中,parameters
是我们定义函数时设置的名字(形参),arguments
(或者是实参)是我们传入函数的参数,看下如下的函数
function foo(param1, param2) {
// do something
}
foo(10, 20);
这个函数里,param1 和 param2 是函数的形参,而我们传入函数的值10,20是实参。
3个示例
var a = 2;
var b = 3;
//例子1
function test1(){
if(b==3){
//使用var声音变量
var c = 3;
}
console.log("c=" + c);
}
test1()
console.log("分隔线")
//例子2
function test2(){
console.log("b:" + b);
var b = 3;
console.log(b);
}
test2();
//例子3
function test3(){
if(b==3){
//注意使用的是es6里的let声明变量
let c = 3;
}
console.log("c=" + c);
}
test3()
console.log("分隔线")
结果如下
c=3
分隔线
b:undefined
3
D:\gitSource\dy\dongli\testScope.js:24
console.log("c=" + c);
^
ReferenceError: c is not defined
at test2 (D:\gitSource\dy\dongli\testScope.js:24:21)
at Object. (D:\gitSource\dy\dongli\testScope.js:26:1)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
为什么会有这个结果呢?
js解析代码按如下阶段执行的
1. 语法分析(分析语法)
2. 预编译(预处理js文件)
3. 解释执行(边解释边执行)3
js是单线程执行,es5之前(注意es6之后加入了let和const声明变量,但javascript是不认的,预编译时会把它当成普通代码)javascript中的两种声明方式,var和function,前者声明的是变量,后者声明的是方法。对应的预编译阶段也有两种处理方案
使用var定义的变量在内存中开辟一块内存空间并指向变量名,且赋值为undefined,使用function声明的函数,则同样会进行开辟内存空间,但赋值的对象会将声明的函数赋值给函数名。
预编译阶段会先声明变量名,再声明函数名,不管代码中声明变量和声明函数的顺序如何。
以上面例子为便解释过来
js引擎扫描js代码块(js里以