本文为拉勾网大前端高薪训练营第一期笔记
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
ps:mozilla解释真的是太详细了
var会提升到代码最前声明,但是不赋值
let不会
var会全局变量
let只会在块作用域里
const就是常量的let,必须在声明时赋值
数组解构可以简化代码
对象解构可以:anotherName换变量名
模板字符串方便拼接字符串和变量
带标签的模板字符串可以增加额外操作,不过最后return的拼接略显麻烦
字符串的扩展方法includes startsWith endsWith,比较好用,不过lodash的这几个可以处理string undefined的情况
参数默认值function(a=1){}很方便处理空输入的情况
剩余参数…rest便捷提取剩余参数,或者是便捷传递给后续模块
展开数组 同上
func.call apply bind
call和apply第一个传参是context,第二个有所不同call是依次,apply是array
bind是把function变成不立马执行,执行时用第一个传参当context
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
简写函数,x ⇒ x+1
Before arrow functions, every new function defined its own this value based on how the function was called
An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in the current scope, an arrow function ends up finding the this from its enclosing scope.
我的理解是()⇒{} 等效于(function(){}).bind(this),箭头函数的this在定义的时候决定,普通function的this是在执行时决定,setTimeout其实是window.setTimeout.bind(window, function(){}, 1000),导致这种时候this是window
有两种scope,global和local,local有两种function scope and block scope
function scope顾名思义,block scope就是{},这个里的const let传不出去
举例
for (var i=1; i<=5; i++) {
setTimeout(function(){
console.log("i: " + i);
},i*1000);
}
拿到的是6 6 6 6 6,
解决方法是
IIFE:Immediately-invoked Function Expression
可以隔离变量,生成新的i
for (var i=1; i<=5; i++) {
(function(i){
setTimeout(function(){
console.log("i: " + i);
}, i*1000);
})(i);
} // 1 2 3 4 5
或者
使用let,此时每个循环都有一个新的i
for (let i=1; i<=5; i++) {
setTimeout(function(){
console.log("i: " + i);
}, i*1000);
}
// 1 2 3 4 5
支持rest parameters和default paraments
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
statements }
Destructuring within the parameter list is also supported
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
箭头函数不允许call apply传入this,会无视掉
没有arguments,想用的话用剩余参数
var f = (…args) => args[0] + n;
一些定义key的简写
const bar = ‘345’
const obj = {
bar,
// 方法可以省略 : function
method1 () {
},
[bar]: 123
}
const result = Object.assign(target, source1, source2)
可以用于对象浅拷贝
Object.is() 高级版的===,解决一些===都判断不出来的情况
// +0 === -0 // => true
// NaN === NaN // => false
// Object.is(+0, -0) // => false
// Object.is(NaN, NaN) // => true
getPrototypeOf: Object.getPrototypeOf()
setPrototypeOf: Object.setProtoTypeOf()
isExtensible: Object.isExtensible()
preventExtensions: Object.preventExtensions()
getOwnPropertyDescriptor: ObjectgetOwnPropertyDescriptor()
defineProperty: Object.defineProperty()
has: in operator
get: getting property values
set: setting property values
deleteProperty: delete operator
ownKeys: Object.getOwnPropertyName and Object.getOwnPropertySymbols
apply: function call
construct: new operator
Reflect
Reflect.apply(target, thisArgument, argumentsList)
//Calls a target function with arguments as specified by the argumentsList parameter.
Reflect.construct(target, argumentsList[, newTarget])
//The new operator as a function. Equivalent to calling new target(…argumentsList).
Reflect.defineProperty(target, propertyKey, attributes)
//Similar to Object.defineProperty(). Returns a Boolean that is true if the property was successfully defined.
Reflect.deleteProperty(target, propertyKey)
//The delete operator as a function. Equivalent to calling delete target[propertyKey].
Reflect.get(target, propertyKey[, receiver])
//Returns the value of the property. Works like getting a property from an object (target[propertyKey]) as a function.
Reflect.getOwnPropertyDescriptor(target, propertyKey)
//Similar to Object.getOwnPropertyDescriptor(). Returns a property descriptor of the given property if it exists on the object, undefined otherwise.
Reflect.getPrototypeOf(target)
//Same as Object.getPrototypeOf().
Reflect.has(target, propertyKey)
//Returns a Boolean indicating whether the target has the property. Either as own or inherited. Works like the in operator as a function.
Reflect.isExtensible(target)
//Same as Object.isExtensible(). Returns a Boolean that is true if the target is extensible.
extensible指的是can new properties be added to an object
Make object not extensible
Object.preventExtensions(), Object.seal(), or Object.freeze().
freeze完全不能修改,seal只是不能增加和删除property
Reflect.ownKeys(target)
//Returns an array of the target object’s own (not inherited) property keys.
Reflect.preventExtensions(target)
//Similar to Object.preventExtensions(). Returns a Boolean that is true if the update was successful.
Reflect.set(target, propertyKey, value[, receiver])
//A function that assigns values to properties. Returns a Boolean that is true if the update was successful.
Reflect.setPrototypeOf(target, prototype)
//A function that sets the prototype of an object. Returns a Boolean that is true if the update was successful.
promise解决传统异步编程中回调函数嵌套过深的问题
add clear delete entries forEach has keys values [@@iterator]()
const mySet = new Set();
const setIter = mySet[Symbol.iterator]()
console.log(setIter.next().value)
const arr = []
Array.from(new Set(arr))
[…new Set(arr)]
Symbol 两个 Symbol 永远不会相等,除非是Symbol.for(true) === Symbol.for(‘true’) 或者是Symbol.for(‘foo’) === Symbol.for(‘foo’)
const symbol = Symbol(‘foo’)
for in,Object.keys(), JSON.stringify()都拿不到symbol key,只有Object.getOwnPropertySymbols(obj)能拿到
for用于array, for in用于object,将来都用for of
需要注意的是for of用于Map的时候每次拿到的是[key, value]
普通obj不能用for of
//便捷写法
// for (const [key, value] of m) {
// console.log(key, value)
// }
只有Iterable的数据类型才能for of
Iterable是指实现了[Symbol.iterator]的数据类型
Iterator是return next的那个function
const obj = {
store: ['foo', 'bar', 'baz'],
[Symbol.iterator]: function () {
let index = 0
return {
next: ()=>{
const result = {
value: this.store[index],
done: index >= this.store.length
}
index++
return result
}
}
}
}
实现迭代器接口的意义是统一遍历接口,外部不需要考虑内部数据结构
Generator yield是惰性抽一次动一次,return是直接结束
ES2016增加了
arr.includes(‘foo’)
2 ** 10 === Math.pow(2, 10)
Object.entries(obj),用这个转一次就能for of了
for (const [key, value] of Object.entries(obj)) {
console.log(key, value)
}
// const p1 = {
// firstName: 'Lei',
// lastName: 'Wang',
// get fullName () {
// return this.firstName + ' ' + this.lastName
// }
// }
// // console.log(p1.fullName)
// // const p2 = Object.assign({}, p1)
此时p2里fullName: 'Wang Lei’是一个key value,并不是getter function
const name = ‘123’
name.padStart(10, ‘-’)
name.padEnd(5, 0)
本文为拉勾网大前端高薪训练营第一期笔记