溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript與ES的重要知識點(diǎn)有哪些

發(fā)布時(shí)間:2020-09-18 09:24:58 來源:億速云 閱讀:203 作者:小新 欄目:web開發(fā)

小編給大家分享一下JavaScript與ES的重要知識點(diǎn)有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

前言

說起JavaScript,大家都知道是一門腳本語言。那么ES是什么鬼呢?ES全稱ECMAScript ,是JavaScript語言的國際標(biāo)準(zhǔn)。

最近總結(jié)了條js的基礎(chǔ)特性相關(guān)的知識點(diǎn),大家一起看一下吧

1.嚴(yán)格模式

  • 使用嚴(yán)格模式,可以在函數(shù)內(nèi)部進(jìn)行較為嚴(yán)格的全局和局部的錯誤條件檢查
  • 嚴(yán)格模式的編譯指示,"use strict"
  • 創(chuàng)建全局變量,未聲明變量,非嚴(yán)格模式下為創(chuàng)建全局變量;嚴(yán)格模式下為拋出ReferenceError
  • 對變量調(diào)用delete操作符,刪除變量,非嚴(yán)格模式下為靜默失敗;嚴(yán)格模式下為拋出ReferenceError
  • 操作對象情況下:a,只讀屬性賦值會拋出TypeError;b,對不可配置的屬性使用delete操作符會拋出TypeError;c,為不可擴(kuò)展的對象添加屬性會拋出TypeError。
  • 重名屬性情況:a,非嚴(yán)格模式下沒有錯誤,以第二個屬性為準(zhǔn);b,嚴(yán)格模式下會拋出語法錯誤。
  • 函數(shù)參數(shù)必須唯一,重名參數(shù),在非嚴(yán)格模式下沒有錯誤,只能訪問第二個參數(shù);嚴(yán)格模式下,會拋出錯誤。
function funValue(value) {
    value="dada";
    alert(value); // dada
    alert(argument[0]); // 非嚴(yán)格模式:dada
    // 嚴(yán)格模式模式 dadaqianduan}

funValue('dadaqianduan');復(fù)制代碼
  • 訪問arguments.callee和arguments.caller,在非嚴(yán)格模式下沒有問題,嚴(yán)格模式下拋出TypeError。

2.Class基礎(chǔ)語法

在JavaScript當(dāng)中如何聲明一個類?如何定義類中的方法?如何實(shí)例化對象?

我們來看看下面的代碼示例:

// es5let dada = function(type) {    this.type = type
}

dada.prototype.study = function() {    console.log('魔王哪吒');
}let da1 = new dada('程序員')let da2 = new dada('It')

da1.constructor.prototype.study = function() {    console.log('dadaqianduan');
}
da1.study()復(fù)制代碼

JavaScript constructor 屬性

定義和用法

constructor 屬性返回對創(chuàng)建此對象的數(shù)組函數(shù)的引用。

語法

object.constructor

constructor 是一種用于創(chuàng)建和初始化class創(chuàng)建的對象的特殊方法。

// es6class Da {  constructor(name) { // 構(gòu)造函數(shù)內(nèi)寫屬性
    this.name = name;
  }
  eat() { // 構(gòu)造函數(shù)外寫方法
    console.log('i eat')
  }
}const da1 = new Da('da1');console.log(da1.name); // da1console.log(da1);復(fù)制代碼
  1. 一個類中只能有一個名為“constructor"的方法,出現(xiàn)多次構(gòu)造函數(shù)constructor方法會拋出一個SyntaxError錯誤
  2. 在一個構(gòu)造方法中可以使用super來調(diào)用一個父類的構(gòu)造方法
  3. 如果沒有指定一個構(gòu)造函數(shù)方法constructor方法,就會使用一個默認(rèn)的構(gòu)造函數(shù)

3.類的屬性Setter和Getter

var daObj = {
 get val() {
  return ;
 },
 set val(value) {
 }
}復(fù)制代碼

get:

var da = {    a: 1,
    get val(){        return this.a + 1;
    }
}console.log(da.val);//2da.val = 100;console.log(da.val);//2class Da { constructor(type) {  this.type = type
 }
 get age() {  return 1
 }
 set age(val) {  this.realAge = val
 }
 eat() {  console.log('i am eat')
 }
}let da1 = new Da('da1')console.log(da1.age)
da1.age = 1console.log(da1.realAge)復(fù)制代碼
class Da {
 constructor(type, age) {
  this.type = type
  this.age1 = age
 }
 get age() {
  return this._age
 }
 set age(val) {
  this._age = val
 }
}復(fù)制代碼

利用set/get實(shí)現(xiàn)對element.innerHTML封裝

class myHTMLElement {
 constructor(element) {
  this.element = element
 }
 get html() {
  return this.element.innerHTML
 }
 set html(value) {
  this.element.innerHTML = value
 }
}復(fù)制代碼

設(shè)置一個閉包,通過一定的規(guī)則來限制對它的修改:

let myName = 'dada'
class Da {
 constructor(type) {
  this.type = type
 }
 get name() {
  return myName
 }
 set name(val) {
  myName = val
 }
}復(fù)制代碼

4.靜態(tài)方法

在es5中實(shí)現(xiàn)的靜態(tài)方法:

let Da = function (type) { this.type = type this.eat = function() {  console.log('i eat')
 }
}
Da.study = function(book) { console.log('i book');
}復(fù)制代碼
let Da = function(type) { this.type = type
}
Da.prototype.eat = function() {
 Da.walk() console.log('i am')
}
Da.walk = function(){ console.log('walk')
}let da1 = new Da('da1')
da1.eat()// walk// i am復(fù)制代碼

靜態(tài)方法在你的實(shí)例化對象是找不到的

在es6中的靜態(tài)方法,標(biāo)記static

class Da {
 constructor(type) {
  this.type = type
 }
 eat() {
  console.log('i eat')
 }
 static study() {
  console.log('i study')
 }
}復(fù)制代碼

5.如何繼承一個類

在es5中的繼承:

// 定義一個父類
let Da = function(type) {
 this.type = type
}
// 定義方法
Da.prototype.eat = function() {
 console.log('i am')
}
// 定義靜態(tài)方法
Da.study = function(book) {
 console.log('i study')
}
// 定義子類
let Da1 = function() {
 // 初始化父類
 Da.call(this, 'da1');
 this.run = function() {
  console.log('i run')
 }
}
// 繼承
Da1.prototype = Da.prototype復(fù)制代碼

在es6中的繼承

class Da { constructor(type) {  this.type = type
 }
 eat() {  // Da.walk();
  console.log('i eat')
 } static walk(){  console.log('i walk')
 }
}class da extends Da { // 構(gòu)造函數(shù)
 //constructor (type) {
  //super(type)
 //}
 run() {  console.log('i run')
 }
}let da1 = new da('da1')復(fù)制代碼

6.面向?qū)ο缶幊藽lass

類的聲明,屬性,方法,靜態(tài)方法,繼承,多態(tài),私有屬性

// 類的聲明
let Da = function(type) {
 this.type = type
 this.eat = function() {
  console.log('i eat');
 }
}

let da = new Da('da');復(fù)制代碼
// prototype
let Da = function(type) {
 this.type = type
}
Da.prototype.eat = function() {
 console.log('i eat')
}
let da1 = new Da('da1')復(fù)制代碼

es6中的Class

class Da {
 // 構(gòu)造函數(shù)
 constructor(type) {
  this.type = type
 }
 // 方法
 walk() {
  console.log('i walk')
 }
}
let da = new Da('da');
// console.log(typeof Da); function復(fù)制代碼

7.函數(shù)參數(shù)的默認(rèn)值

函數(shù)參數(shù)是從左到右解析,如果沒有默認(rèn)值會被解析成 undefined

// 參數(shù)默認(rèn)值
function da (x,y,z) {
}
function sum() {
 let num = 0
 Array.prototype.forEach.call(arguments, function(item){
  num += item * 1
 })
 Array.from(arguments).forEach(function(item){
  num += item * 1
 })
 return num
}復(fù)制代碼
// 不確定
function sum(...nums) {
 let num = 0
 nums.forEach(function(item){
  num += item * 1
 })
 return num
}
console.log(sum(1,2,3,4,5))復(fù)制代碼
function sum () {
  let num = 0
  Array.prototype.forEach.call(arguments, function (item) {
    num += item * 1
  })
  return num
}

function sum (...nums) {
  let num = 0
  nums.forEach(function (item) {
    num += item * 1
  })
  return num
}復(fù)制代碼

8.es6箭頭函數(shù)

箭頭函數(shù)表達(dá)式的語法比函數(shù)表達(dá)式更簡潔,并且沒有自己的this,arguments,super或new.target。箭頭函數(shù)表達(dá)式更適用于那些本來需要匿名函數(shù)的地方,并且它不能用作構(gòu)造函數(shù)。

() => {}
// function Da() {}
// let da = function() {}
let da = () => {
 console.log('hello')
}
da()

let da = name => {}復(fù)制代碼
const materials = [  'Hydrogen',  'Helium',  'Lithium',  'Beryllium'];console.log(materials.map(material => material.length));// expected output: Array [8, 6, 7, 9]復(fù)制代碼

拓展

判斷函數(shù)有幾個參數(shù)

  1. 在 ES5 中可以在函數(shù)體內(nèi)使用 arguments 來判斷。
  2. 在 ES6 中可以借助 Function.length 來判斷。(統(tǒng)計(jì)第一個默認(rèn)參數(shù)前面的變量數(shù))
console.log(sum(...[4]))
console.log(sum.apply(null, [4]))復(fù)制代碼

9.JavaScript中的三個點(diǎn)(…)

JavaScript當(dāng)中,函數(shù)的參數(shù)前面有三個點(diǎn),代表什么呢?我們看下代碼示例:

function myFunc(a, b, ...args) {
 console.log(a); // 22
 console.log(b); // 98
 console.log(args); // [43, 3, 26]
};
myFunc(22, 98, 43, 3, 26);復(fù)制代碼
function myFunc(x, y, ...params) { // used rest operator here
  console.log(x);  console.log(y);  console.log(params);
}var inputs = ["a", "b", "c", "d", "e", "f"];
myFunc(...inputs); // used spread operator here// "a"// "b"// ["c", "d", "e", "f"]復(fù)制代碼
var obj1 = { foo: 'bar', x: 42 };var obj2 = { foo: 'baz', y: 13 };var clonedObj = { ...obj1 };// Object { foo: "bar", x: 42 }var mergedObj = { ...obj1, ...obj2 };// Object { foo: "baz", x: 42, y: 13 }復(fù)制代碼

10.Object Property

JS中對象的屬性定義,代碼示例如下:

let x = 'da1';
let y = 'da2';
let obj = {
 x,
 y
}
console.log(obj);

// 結(jié)果
{x:'da1',y:'da2'}復(fù)制代碼
let x=1; let y=2; let z=3
let obj = {
 'x': x,
 y,
 [z+y]: 4,
 * hello() { // 異步
  console.log('dada')
 }
}
// function* functionName() {}
obj.hello()復(fù)制代碼

11.Set數(shù)據(jù)結(jié)構(gòu)

Set存儲的成員不允許的重復(fù)的(它類似于數(shù)組)

Set 本身是一個構(gòu)造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構(gòu)。

const s = new Set();

[2, 3, 5].forEach(x => s.add(x));

Set 函數(shù)可以接受一個數(shù)組(或類似數(shù)組的對象)作為參數(shù),用來初始化

const set = new Set([1, 2, 3, 4, 4]);復(fù)制代碼

實(shí)現(xiàn)數(shù)組去重

var arr = [1,1,2,2,3,3]; // step1:數(shù)組轉(zhuǎn)集合
var s = new Set(arr); // 已經(jīng)去掉重復(fù)值,當(dāng)前不是數(shù)組,而集合
s.size; // 3
// step2:集合轉(zhuǎn)數(shù)組
console.log([...s]); // 1,2,3;

// Array.form 方法可以將 Set 結(jié)構(gòu)轉(zhuǎn)為數(shù)組
const items = new Set([1, 2, 3]);
const arr = Array.from(items);

function dada(array) {
  return Array.from(new Set(array));
}

dada([1, 1, 2])復(fù)制代碼

Set的遍歷

  • keys():返回鍵名的遍歷器
  • values():返回鍵值的遍歷器
  • entries():返回鍵值對的遍歷器
  • forEach():使用回調(diào)函數(shù)遍歷每個成員

操作方法

  • add(value)添加某個值,返回Set結(jié)構(gòu)本身。
  • delete(value)刪除某個值,返回一個布爾值,表示刪除是否成功。
  • has(value)返回一個布爾值,表示該值是否為Set的成員。
  • clear()清除所有成員,沒有返回值。
let set = new Set([1, 2, 3, 4, 4]);

// 添加數(shù)據(jù) 
let addSet = set.add(5);
console.log(addSet); // Set(5) {1, 2, 3, 4, 5}

// 刪除數(shù)據(jù) 
let delSet = set.delete(4);
console.log(delSet); // true

// 查看是否存在數(shù)據(jù) 4
let hasSet = set.has(4);
console.log(hasSet); // false

// 清除所有數(shù)據(jù)
set.clear();
console.log(set); // Set(0) {}復(fù)制代碼

實(shí)現(xiàn)并集(Union)、交集(Intersect)和差集(Difference)

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2, 1]);

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {1, 2, 3}

// 差集
let difference = new Set([...b].filter(x => !a.has(x)));
// Set {4}復(fù)制代碼

12.Map數(shù)據(jù)結(jié)構(gòu)

JS當(dāng)中的哈希表,使用方法如下:

let map = new Map()
map.set(1, 2)
map.set(3, 4)
map.set(1, 3)
console.log(map)

創(chuàng)建
var da = new Map();
var jeskson = {};
遍歷
da.forEach(function(value,key,map){}
長度
da.size
刪除
//da.delete() 刪除key,全部清楚da.clear()
新增
da.set(key,value)
da.has(查索引值)

da.forEach((value,key) =>{
})

for( let [key, value] of map){}

// let map = new Map( [[1,2], [3,4]] )

map的key任意都可以
let o = function() {
 console.log('o')
}
map.set(o, 3)
console.log(map.get(o)); // 3復(fù)制代碼
// map.js
var Dictionary = function() {
 var items = {};
 // 檢查鍵
 this.has = function(key) {
  return key in items;
 }
 // 添加鍵值對
 this.set = function(key, value){
  items[key] = value;
 }
 // 通過鍵移除元素
 this.delete = function(key) {
  if(this.has(key)){
   delete items[key]
   return true
  }
  return false
 }
 // 鍵獲取值
 this.get = function(key){
  return this.has(key) ? items[key] : undefined;
 }
 // 列表返回字典值
 this.values = function() {
  var values = [];
  for(var k in items) {
   if(this.has(k)) {
    values.push(items[k])
   }
  }
  return values;
 }
 // 獲取全部鍵名
 this.keys = function() {
  return Object.keys(items);
 }
 // 獲取私有變量items
 this.getItems = function() {
  return items;
 }
}復(fù)制代碼

Map數(shù)據(jù)結(jié)構(gòu),它類似于對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當(dāng)作鍵。

13.Object.assign(對象的拷貝)

Object.assign() 方法用于將所有可枚舉屬性的值從一個或多個源對象復(fù)制到目標(biāo)對象。它將返回目標(biāo)對象。

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }

> Object { a: 1, b: 4, c: 5 }
> Object { a: 1, b: 4, c: 5 }復(fù)制代碼

語法

Object.assign(target, ...sources)復(fù)制代碼

參數(shù)

target復(fù)制代碼

目標(biāo)對象

sources復(fù)制代碼

源對象

返回值

目標(biāo)對象。

const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }復(fù)制代碼
  • Object.assign()拷貝的是(可枚舉)屬性值
  • Object.assign方法的第一個參數(shù)是目標(biāo)對象,后面的參數(shù)都是源對象
  • 如果目標(biāo)對象與源對象有同名屬性,或多個源對象有同名屬性,則后面的屬性會覆蓋前面的屬性
  • 由于undefined和null無法轉(zhuǎn)成對象,所以如果它們作為參數(shù),就會報(bào)錯
  • 如果undefined和null不在首參數(shù),就不會報(bào)錯
  • 如果源對象某個屬性的值是對象,那么目標(biāo)對象拷貝得到的是這個對象的引用(這個對象的任何變化,都會反映到目標(biāo)對象上面。)
Object.assign(undefined) // 報(bào)錯
Object.assign(null) // 報(bào)錯

let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true

const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);

obj1.a.b = 2;
obj2.a.b // 2

const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }

const source = {
  get foo() { return 1 }
};
const target = {};

Object.assign(target, source)
// { foo: 1 }復(fù)制代碼

Object.assign復(fù)制的是屬性值value,如果屬性值是一個引用類型,那么復(fù)制的其實(shí)是引用地址,就會存在引用共享的問題(Object.assign(target,source1,...,sourceN)淺拷貝的過程)

要點(diǎn):

function ObjectAssign(target, ...sources) {
 // 對第一個參數(shù)的判斷,不能為undefined和null
 if(target === undefined || target === null) {
  throw my TypeError('error');
 }
 // 將第一個參數(shù)轉(zhuǎn)為對象(不是對象轉(zhuǎn)換為對象)
 const targetObj = Object(target);
 // 將源對象自身的所有可枚舉屬性復(fù)制到目標(biāo)對象
 for(let i = 0; i<sources.length; i++){
  let source = sources[i];
  // 對于undefined和null在源中不會報(bào)錯,會直接跳過
  if(source !== undefined && source !== null) {
   // 將源象轉(zhuǎn)換成對象
   // 需要將源自身的可枚舉數(shù)據(jù)進(jìn)行復(fù)制
   // Reflect.ownKeys(obj)
   const keysArray = Reflect.ownKeys(Object(source));
   for (let nextIndex = 0; nextIndex < keysArray.length; nextIndex++) {
    const nextKey = keysArray[nextIndex];
    // 去除不可枚舉屬性
    const desc = Object.getOwnPropertyDescriptor(source,nextKey);
    if(desc!==undefined&&desc.enumerable){
     targetObj[nextKey] = source[nextKey];
    }
   }
  }
 }
 return targetObj;
}
if(typeof Object.myAssign !== 'function'){
 Object.defineProperty(Object, 'myAssign', {
  value: ObjectAssign,
  writable: true,
  enumerable: false,
  configurable: true
 });
}復(fù)制代碼

淺拷貝 Object.assign 的實(shí)現(xiàn)原理

拷貝第一層的基本類似值和第一層的引用類型地址:

let da1 = { name: 'da1', age: 1}let da2 = { name: 'da2', study: {  title: 'web'
 }
}let da3 = Object.assign(da1,da2);console.log(da3);// {// name: 'da2',// age: 1,// study: { title: 'web' }// }console.log( da1 === da3); // trueda2.name = 'da22';
da2.study.title = 'web2';console.log(da2);// {// name: 'da22',// study: { title: 'web2' }// }console.log(da1);// {// age: 1,// name: 'da2',// study: { title: 'web2' }// }復(fù)制代碼

如果源對象的屬性值是一個指向?qū)ο蟮囊?,它也只拷貝這個引用地址哦!

let da1 = { name: 'da1', age: 1}let da2 = { a: Symbol('dadaqianduan'), b: null, c: undefined}let da3 = Object.assign(da1, da2);console.log(da3);// {// name: 'da1',// age: 1,// a: Symbol('dadaqianduan'),// b: null,// c: undefined// }console.log(da1 === da3); // true復(fù)制代碼
let map = new Map([iterable])
// Map是用來實(shí)現(xiàn)字典的功能-Object鍵值對復(fù)制代碼

動態(tài)屬性鍵

// ES5 code
var
  key1 = 'one',
  obj = {
    two: 2,
    three: 3
  };

obj[key1] = 1;

// obj.one = 1, obj.two = 2, obj.three = 3

// ES6 code
const
  key1 = 'one',
  obj = {
    [key1]: 1,
    two: 2,
    three: 3
  };

// obj.one = 1, obj.two = 2, obj.three = 3

// ES6 code
const
  i = 1,
  obj = {
    ['i' + i]: i
  };

console.log(obj.i1); // 1復(fù)制代碼

補(bǔ)充:前端面試考點(diǎn),HTML和CSS,性能優(yōu)化,原型,作用域,異步,各種手寫代碼,DOM事件和Ajax,HTTP協(xié)議。

  • css(布局,定位,移動端響應(yīng)式)
  • es(原型,原型鏈,作用域,閉包,異步,單線程)
  • webapi(DOM BOM,Ajax跨域,事件存儲)
  • 開發(fā)環(huán)境(版本管理,調(diào)試抓包,打包構(gòu)建)
  • 運(yùn)行環(huán)境(頁面渲染,性能優(yōu)化,web安全)
  • 網(wǎng)絡(luò)通訊
  1. 布局(盒模型,BFC,float,flex)
  2. 定位,圖文樣式,移動端響應(yīng)式(rem,media query,vw/vh),動畫、漸變
  3. 變量類型和計(jì)算(值類型和引用類型,類型判斷,邏輯運(yùn)算)
  4. 原型和原型鏈(class,繼承,原型,原型鏈,instanceof)
  5. 作用域和閉包(作用域,自由變量,閉包,this)
  6. 異步(單線程,callback,應(yīng)用場景,Promise,event-loop,async/await,微任務(wù)/宏任務(wù))
  7. 模塊化(ES6 Module)
  8. DOM(樹形結(jié)構(gòu),節(jié)點(diǎn)操作,屬性,樹結(jié)構(gòu)操作,性能)
  9. BOM(navigator,screen,location,history)
  10. 事件(綁定,冒泡,代理)
  11. ajax(XMLHttpRequest,狀態(tài)碼,跨域)
  12. 存儲(cookie,localStorage,sessionStorage)
  13. 開發(fā)環(huán)境(git,調(diào)試,webpack和babel,linux命令)
  14. 運(yùn)行環(huán)境(頁面加載:加載,渲染。性能優(yōu)化:加載資源優(yōu)化,渲染優(yōu)化。安全:xss,CSRF)
  15. HTTP協(xié)議:狀態(tài)碼,Method,Restful API,headers,緩存策略

14.模板文字

模板文字是es2015/es6的新功能,與es5及以下版本相比,可以通過新穎的方式使用字符串,先只需要反引號代替單引號或雙引號即可:

const module_string = `dadaqianduan`復(fù)制代碼

它們之所以獨(dú)特是因?yàn)樗鼈兲峁┝撕芏嘤靡枠?gòu)建的普通字符串不具備的功能:

  1. 提供了定義多行字符串的語法;
  2. 提供了一種簡單的方法來插值字符串中的變量和表達(dá)式
  3. 允許您使用模板標(biāo)簽創(chuàng)建DSL(領(lǐng)域特定的語言)

使用多行字符串

在es6之前的版本:

// 要創(chuàng)建跨越兩行的字符串,必須\在行尾使用字符const dada = 
 'dada \
  dadaqianduan'
  // 呈現(xiàn)效果:在兩行上創(chuàng)建一個字符串,但是僅在一行上呈現(xiàn)復(fù)制代碼

要在多行上呈現(xiàn),則需要使用\n在每行的末尾添加

const string = 
 'dada 魔王哪吒\n \
  dadaqianduan'復(fù)制代碼

使用反引號打開模板文字后,只需要按enter鍵就行:

const dada = `dadaqianduan 
魔王哪吒`復(fù)制代碼

在這里請記住空間是有意義的:

const da = `First
            Second`復(fù)制代碼

使用trim()方法,可以消除第一個字符之前的任何空格

插補(bǔ):模板文字提供了一種將變量和表達(dá)式插入字符串的簡便的方法

const da = `dadaqianduan ${mydada}`

${}里面可以添加任何東西

const da1 = `dada ${1+2+3}`
const da2 = `dada ${dafun() ? 'x' : 'y'}`復(fù)制代碼

15.什么是解構(gòu)賦值

let da = ['hello', 'world']
let [firstName, surName] = da
cosole.log(firstName, surName);復(fù)制代碼

解構(gòu)賦值在于賦值,拷貝出來賦值給變量,而賦值的元素本身不會發(fā)生改變

默認(rèn)值

let [da1, da2] = [];console.log(da1); // undefinedconsole.log(da2); // undefined復(fù)制代碼

給變量賦值(默認(rèn)值),防止出現(xiàn)undefined的情況:

let [da1= 'da1', da2 = 'da2']=['dadaqianduan]

console.log(da1); // dadaqianduan
console.log(da2); // da2復(fù)制代碼

解構(gòu)分配

ES5中的索引提取這些值:

var myArray = ['a', 'b', 'c'];var
  one   = myArray[0],
  two   = myArray[1],
  three = myArray[2];// one = 'a', two = 'b', three = 'c'復(fù)制代碼

ES6解構(gòu)允許使用更簡單方法:

const [one, , three] = myArray;// one = 'a', three = 'c'復(fù)制代碼

使用rest運(yùn)算符(...)提取剩余元素:

const [one, ...two] = myArray;// one = 'a', two = ['b, 'c']復(fù)制代碼
const myObject = {  one:   'a',  two:   'b',  three: 'c'};// ES6 destructuring exampleconst {one: first, two: second, three: third} = myObject;// first = 'a', second = 'b', third = 'c'復(fù)制代碼

可變值交換

var a = 1, b = 2;// ES5 swapvar temp = a;
a = b;
b = temp;// a = 2, b = 1// ES6 swap back[a, b] = [b, a];// a = 1, b = 2[b, c, d, e, a] = [a, b, c, d, e];復(fù)制代碼

在ES6中,我們可以為任何參數(shù)分配默認(rèn)值

function dada(param = {}) {復(fù)制代碼

函數(shù)返回多個值(函數(shù)只能返回一個值,但可以是一個復(fù)雜的對象或多維數(shù)組)

function f() {  return [1, 2, 3];
}const [a, b, c] = f();// a = 1, b = 2, c = 3復(fù)制代碼

ES6 JavaScript深度解構(gòu)

默認(rèn)情況下,找不到的屬性為undefined

var {da} = {bar: 'dada'}console.log(da)// undefined復(fù)制代碼

如果訪問不存在的父級的深層嵌套屬性,則將獲得異常。

var {da:{bar}} = {dada: 'dadaqianduan'}// Exception復(fù)制代碼
var key = 'dadaqianduan'var { [key]: foo } = { dadaqianduan: 'bar' }console.log(foo)// 'bar'復(fù)制代碼
var {da=3} = { da: 2 }console.log(da)// 2var {da=3} = { da: undefined }console.log(da)// 3var {da=3} = { bar: 2 }console.log(da)// 3var [a] = []console.log(a)//  undefinedvar [b=10] = [undefined]console.log(b)//  10var [c=10] = []console.log(c)//  10function da () {  return {    x: 1,    y: 2
  }
}var {x, y} = da()console.log(x)// 1console.log(y)// 2復(fù)制代碼

16.異步操作

Callback

Promise

function loadScript(src) { return new Promise((resolve, reject) => {  let script = document.createElement('script')
  script.src = src
  script.onload = () => resolve(src)
  script.onerror = (err) => reject(err)  document.head.append(script)
 })
}復(fù)制代碼
function loadScript(src) { let script = document.createElement('script');
 script.src = src; document.head.append(script)
}復(fù)制代碼
var promise = new Promise(function(resolve, reject){
 resolve('傳遞給then的值')
})
promise.then(function(value){
 console.log(value)
},function(error){
 console.error(error)
})復(fù)制代碼

Promise對象是用于表示一個異步操作的最終完成(或失?。?,以及其結(jié)果值。

示例:

const promise = new Promise((resolve, reject) => {
 setTimeout(() => {
  resolve('da');
 }, 200);
});

promise.then((value) => {
 console.log(value);
});

console.log(promise);復(fù)制代碼

語法:

new Promise(function (resolve,reject){...});復(fù)制代碼

描述:Promise對象是一個代理對象,被代理的值在Promise對象創(chuàng)建時(shí)可能是未知的,它允許你為異步操作的成功和失敗分別綁定相應(yīng)的處理方法,這讓異步方法可以像同步方法那樣返回值,但并不是立即返回最終執(zhí)行結(jié)果,而是一個能代表未來出現(xiàn)的結(jié)果的promise對象。

一個Promise有以下幾種狀態(tài):

  1. pending,初始狀態(tài),既不是成功,也不是失敗狀態(tài)。
  2. fulfilled,意味著操作成功完成。
  3. rejected,意味著操作失敗。

pending狀態(tài)的Promise對象可能會變?yōu)閒ulfilled狀態(tài)并傳遞一個值給相應(yīng)的狀態(tài)處理方法。

Promise.prototype.thenPromise.prototype.catch方法返回promise對象,所以它們可以被鏈?zhǔn)秸{(diào)用。

方法:

Promise.all(iterable)

  1. 返回一個新的promise對象
  2. 在iterable參數(shù)對象里所有的promise對象都成功時(shí),才會觸發(fā)成功
  3. 當(dāng)任何一個iterable里面的promise對象失敗,才會觸發(fā)promise對象的失敗
  4. 成功狀態(tài)會把一個包含iterable里所有promise返回值的數(shù)組作為成功回調(diào)的返回值,順序和iterable的順序一樣
  5. 如果這個新的promise對象觸發(fā)了失敗,會把iterable里的第一個觸發(fā)失敗的promise對象的錯誤信息作為它的失敗信息
  6. 場景,多用于處理多個promise對象的狀態(tài)集合

Promise.any(iterable)

  1. 接收一個Promise對象的集合,當(dāng)其中的一個promise成功,就返回那個成功的promise的值

Promise.reject(reason)

  1. 返回一個狀態(tài)為失敗的Promise對象,然后將失敗信息傳遞給對應(yīng)的處理方法

Promise.resolve(value)

  1. 返回一個狀態(tài)由給定value決定的Promise對象

Promise原型

屬性:Promise.prototype.constructor返回被創(chuàng)建的實(shí)例函數(shù),默認(rèn)為Promise函數(shù)。

方法:

  • Promise.prototype.catch(onRejected)
  • Promise.prototype.then(onFulfilled,onRejected)
  • Promise.prototype.finally(onFinally)
function myAsyncFunction(url) { return new Promise((resolve, reject) => {  const xhr = new XMLHttpRequest();
  xhr.open('GET',url);
  xhr.onload = () => resolve(xhr.responseText);
  xhr.onerror = () => reject(xhr.statusText);
  xhr.send();
 });
}復(fù)制代碼

17.ES6代理

  1. 默認(rèn)情況下,代理不執(zhí)行任何操作

示例:

var target = {}var handler = {}var proxy = new Proxy(target, handler)
proxy.a = 'b'console.log(target.a)// 'b'console.log(proxy.c === undefined)// true復(fù)制代碼

為了更好地了解代理的有用性,讓我們做一些小練習(xí)。

示例:

想象一下,您已經(jīng)17歲了,即將滿18歲。并且您希望您的程序在打開時(shí)自動向您祝賀。為此,您可以使用代理。

var person = {  name: "dada",  age: 17};

person = new Proxy(person, {
  set(target, property, value) {    if (value === 18) {      console.log("Congratulations! You are of legal age");      Reflect.set(target, property, value);      return true;
    }
  }
});

person.age = 18;if (value < 13 && value > 99) {  throw new Error('The age should be between 13 and 99')
} else {  Reflect.set(target, property, value)
}復(fù)制代碼

語法:

let p = new Proxy(target, handler)復(fù)制代碼
  1. target 用Proxy包裝的目標(biāo)對象
  2. handler 一個對象,其屬性是當(dāng)執(zhí)行一個操作時(shí)定義代理的行為的函數(shù)

如果不想再調(diào)用key的時(shí)候,返回undefined:

console.log(o.dada || '')復(fù)制代碼

使用Proxy

let o = {
 name: 'dada', age: 1}let handler = {
 get(obj, key) {  return Reflect.has(obj, key)?obj[key]:''
 }
}let p = new Proxy(o, handler)console.log(p.from)復(fù)制代碼

希望從服務(wù)器獲取的數(shù)據(jù)只讀,不允許修改:

for (let [key] of Object.entries(response.data)) { 
 Object.defineProperty(response.data, key, {
  writable: false
 })
}復(fù)制代碼

使用Proxy:

let data = new Proxy(response.data, {
 set(obj, key, value) {   return false
 }
})復(fù)制代碼

檢驗(yàn)邏輯代碼:

// Validator.jsexport default(obj, key, vlaue) => { if(Reflect.has(key) && value > 20) {
  obj[key] = value
 }
}import Validator from './Validator'let data = new Proxy(response.data, { set: Validator
})復(fù)制代碼

使用Proxy,對讀寫進(jìn)行監(jiān)控:

let validator = {
 set(target, key, value) {  if(key === 'age') {   if(typeof value !== 'number' || Number.isNaN(value)) {    throw new TypeError('Age must be a number')
   }   if(value<=0){    throw new TypeError('Age must be a positive number')
   }
  }  return true
 }
}const person = { age: 12 }const proxy = new Proxy(person,validator)
proxy.age = 'dada' // TypeError numberproxy.age = NaNproxy.age = 0 // positive numberproxy.age = 3復(fù)制代碼

示例:每個對象都有一個自己的id

class Component { constructor() {  this.proxy = new Proxy({   id: Math.random().toString(36).slice(-8)
  })
 }
 get id() {  return this.proxy.id
 }
}復(fù)制代碼

18.Generator

function * dada() {
 for(let i=0; i<2; i++ {
  yield console.log(i);
 }
}

const da = dada()
da.next()
da.next()復(fù)制代碼

Generator函數(shù)與普通函數(shù)的區(qū)別在于定義的時(shí)候有一個*,執(zhí)行下面函數(shù):

function* dada() {
console.log('dadaqianduan');
}
dada(); // 沒有執(zhí)行函數(shù)
 
如需要輸出,改為:
var da = dada();
da.next();復(fù)制代碼

要生成一個自增的id:

var count_id = 0;
function dada_id() {
count_id ++;
return count_id;
}復(fù)制代碼

方法

Generator.prototype.next()
返回一個由 yield表達(dá)式生成的值。

Generator.prototype.return()
返回給定的值并結(jié)束生成器。

Generator.prototype.throw()
向生成器拋出一個錯誤。復(fù)制代碼

書寫風(fēng)格:

function *da() {
}

function* da(){
}復(fù)制代碼

方法

Generator對象方法:next,return,throw

通過Next方法來獲取每一次遍歷的結(jié)果,這個方法返回一個對象,這個對象包含兩個value和done。

value:當(dāng)前程序的運(yùn)行結(jié)果 done:遍歷是否結(jié)束

next是可以接收參數(shù)的,這個參數(shù)可以讓你在generator外部給內(nèi)部傳遞數(shù)據(jù),這個參數(shù)就是作為yield的返回值。

return()方法可以讓generator遍歷終止

function * da() {
 yield 1
 yield 2
 yield 3
}
var d = da()
console.log(d.next()) // {value:1,done:false}
console.log(d.return()) // {value:undefined,done:true}
console.log(d.next()) // {value:undefined,done:true}復(fù)制代碼

return可以傳入?yún)?shù),作為返回的value的值

function * da() {
 yield 1
 yield 2
 yield 3
}
var d = da()
console.log(d.nex()) // {value:1,done:false}
console.log(d.return(100)) // {value:100,done:true}
console.log(d.next()) // {value:undefined,done:true}復(fù)制代碼

throw()方法在generator外部控制內(nèi)部執(zhí)行的“終斷”

generator函數(shù)聲明:

function* genFunc(){...}
const genObj = genFunc();復(fù)制代碼

generator表達(dá)式:

const genFunc = function* () {...}
const genObj = genFunc();復(fù)制代碼

對象中定義:

const obj = {
 * generatorMethod(){
  ...
 }
}
const genObj = obj.generatorMethod();復(fù)制代碼

類定義(類聲明或類表達(dá)式):

class MyClass{
 * generatorMethod(){
  ...
 }
}
const myInst = new MyClass();
const genObj = myInst.generatorMethod();復(fù)制代碼

最簡單的iterator遍歷規(guī)范:

authors[Symbol.iterator] = function(){
 // this
 return {
  next(){
   return{
    done:false,
    value:1
   }
  }
 }
}復(fù)制代碼

19.module

在es6前,js文件之間的導(dǎo)入,導(dǎo)出是借助require.js,sea.js,如現(xiàn)在使用import,export,來實(shí)現(xiàn)原生javascript的導(dǎo)入,導(dǎo)出。

export:

導(dǎo)出變量或者常量

export const da = 'dadaqianduan'
export let da1 = 'da1'
export var da2 = 'da1'

const name = 'dada'
let name1 = 'dada1'
export {
 name,
 name1
}

導(dǎo)出函數(shù)
export function da(value){
 console.log(value)
}

const da = (value) => {
 console.log(value);
}

export {
 da
}

導(dǎo)出Object
export({
 name: 'da1',
 message: 'dadaqianduan'
})

let da = {
 name: 'name1'
}
export {
 da
}

導(dǎo)出Class
class Da {
 constructor(){
  this.id = 1
 }
}
export {
 Da
}

export class Da {
 constructor() {
  this.id = 1
 }
}

修改導(dǎo)出名稱
const name = 'da1'
export {
 name as cname
}
export default name復(fù)制代碼

import

// 直接導(dǎo)入
const name = 'dada'
let name1 = 'dada1'
var name2 = 'dada2'
export {
 name as cname
}
export default name2

import name2, {name1, name} from A復(fù)制代碼
export const sqrt = Math.sqrt;
export function square(x) {
 return x * x;
}
export function dada(x,y) {
 return sqrt(square(x) + square(y));
}

import {square,da} from 'da';
console.log(square(11)); // 121
console.log();復(fù)制代碼
export default function() {...}
import myFunc from 'myFunc';
export default class{...}
import MyClass from 'MyClass';
const inst = new MyClass();復(fù)制代碼

20.import, export

require
--lib.js--
function add(x,y){
 return x + y
}
module.exports = {
 add: add,
};

--main.js--
var add = require('lib').addd;
console.log(add(1,2));復(fù)制代碼
import
--lib.js--
export function add(x,y) {
 return x + y
}
--main.js--
import {add} from 'lib';
console.log(add(1,2));復(fù)制代碼
--lib.js--
export const sqrt = Math.sqrt;
export function square(x) {
 return x * x;
}
export function da(x,y) {
 return sqrt(square(x)+square(y));
}
--main.js--
import {square, da} from 'lib'


--myFunc.js--
export default function() {...};
--main.js--
import myFunc from 'myFunc';
myFunc();復(fù)制代碼

21.Array.prototype.includes,Promise

該方法判斷一個數(shù)組是否包含一個指定的值,返回布爾值

let da1 = [1,2,3];
console.log(da1.includes(2));復(fù)制代碼
arr.find(function(item){
return item === 1;
})

arr.filter(function(item){
return item === 2;
})

Math.pow(2,3)->2**3復(fù)制代碼
async function firstAsync(){
 let promise = new Promise ((resolve,reject) => {
  setTimeout(function(){
   resolve('dadaqianduan')
  },1000)
 })
 console.log(await promise)
 console.log(await Promise.resolve(1))
 console.log(2)
 return Promise.resolve(3)
}
firstAsync().then(val => {
 console.log(val)
})復(fù)制代碼

await后面是Promise對象

Object.values()返回一個數(shù)組,其元素是再對象上找到的可枚舉屬性值。

let da = {
 'da': 1,
 'da2': 2
}
console.log(Object.value(da)) // [1,2]

Object.values是在對象上找到可枚舉的屬性的值,所以只要這個對象是可枚舉的就可以復(fù)制代碼

Object.entries()方法返回一個給定對象自身可枚舉屬性的鍵值對數(shù)組

22.JS異步進(jìn)階

題目一:

Promise.resolve().then(()=>{
 console.log(1)
}).catch(()=>{
 console.log(2)
}).then(()=>{
 console.log(3)
})復(fù)制代碼

題目二:

Promise.resolve().then(()=>{
 console.log(1)
 throw new Error('da')
}).catch(()=>{
 console.log(2)
}).then(()=>{
 console.log(3)
})復(fù)制代碼

題目三:

Promise.resolve().then(()=>{
 console.log(1)
 throw new Error('da')
}).catch(()=>{
 console.log(2)
}).catch(()=>{
 console.log(3)
})復(fù)制代碼

題目四:

async function fn() {
 return 1
}
(async function() {
 const a = fn() // ??
 const b = await fn() // ??
})()復(fù)制代碼

題目五:

console.log(100)
setTimeout( () => {
 console.log(200)
})
Promise.resolve().then( ()=> {
 console.log(300)
})
console.log(400)復(fù)制代碼

題目六:

async function async1() {
 console.log('async1 start')
 await async2()
 console.log('async1 end')
}

async function async2 () {
 console.log('async2')
}

console.log('script start')

setTimeout(function(){
 console.log('setTimeout')
},0)

async1()

new Promise(function (resolve){
 console.log('promise1')
 resolve()
}).then(function(){
 console.log('promise2')
})

console.log('script end')復(fù)制代碼

加載圖片:

// 加載
function  loadImg(src) {
 const p = new Promise(
  (resolve,reject) => {
   const img = document.createElement('img')
   img.onload = () =>{
    resolve(img)
   }
   img.onerror = () =>{
    const err = new Error('圖片加載失敗')
    reject(err)
   }
   img.src = src
  }
 )
 return p
}
const url = 'https'
const p = loadImg(url)

p.then(img =>{
 console.log(img.width)
 return img
}).then(img =>{
 console.log(img.height)
}).catch(ex => {
 console.error(ex)
})復(fù)制代碼
async function async1() {
 console.log('async1 start') // 2
 await async2() // undefined
 console.log('async1 end') // 5
}
async function async2() {
 console.log('async2') // 3
}
console.log('script start') // 1
async1()
console.log('script end') // 4復(fù)制代碼

for...of常用于異步的遍歷

function add(num) {
 return new Promise(resolve => {
  setTimeout(()=>{
   resolve(num*num)
  },1000)
 })
}
const nums = [1,2,3]
nums.forEach(async(i)=>{
 const res = await add(i)
})復(fù)制代碼

23.宏任務(wù)和微任務(wù)

宏任務(wù):setTimeout,setInterval,ajax等 微任務(wù):Promise async/await

微任務(wù)執(zhí)行時(shí)比宏任務(wù)要早:

宏任務(wù):DOM渲染后觸發(fā),如setTimeout

微任務(wù):DOM渲染前觸發(fā),如Promise

24.For await of 異步操作集合

function da(time) {
 return new Promise(function(resolve,reject){
  setTimeout(function(){
   resolve(time)
  },time)
 })
}
async function test() {
 let arr = [da(2000),da(1000),da(3000)]
 for await (let item of arr) {
  console.log(Date.now(), item)
 }
}復(fù)制代碼
const input = {
 a: 1,
 b: 2
}
const output = {
 ...input,
 c: 3
}
console.log(output)

const input = {
 a: 1,
 b: 2,
 c: 3
}
let {a, ...rest } = input復(fù)制代碼

25Array.prototype.flat()

該方法會按照一個可指定的深度遞歸遍歷數(shù)組,并將所有元素與遍歷到的子數(shù)組中的元素合為一個新數(shù)組。

Array.prototype.flat()建議將數(shù)組遞歸展平至指定范圍depth并返回新數(shù)組。

depth(指定要提取嵌套數(shù)組的結(jié)構(gòu)深度)

語法:Array.prototype.flat(depth)

depth —默認(rèn)值1,Infinity用于展平所有嵌套數(shù)組。

const numbers = [1, 2, [3, 4, [5, 6]]];

// Considers default depth of 1
numbers.flat(); 

> [1, 2, 3, 4, [5, 6]]

// With depth of 2
numbers.flat(2); 

> [1, 2, 3, 4, 5, 6]

// Executes two flat operations
numbers.flat().flat(); 

> [1, 2, 3, 4, 5, 6]

// Flattens recursively until the array contains no nested arrays

numbers.flat(Infinity)
> [1, 2, 3, 4, 5, 6]復(fù)制代碼

語法:Array.prototype.flatMap(callback)

callback:function產(chǎn)生新Array的元素。

const numbers = [1, 2, 3];

numbers.map(x => [x * 2]);
> [[2], [4], [6]]

numbers.flatMap(x => [x * 2]);
> [2, 4, 6]復(fù)制代碼

Object.fromEntries

Object.fromEntries執(zhí)行與的相反操作Object.entries。它將一組鍵值對轉(zhuǎn)換為一個對象。

const records = [['name','da'], ['age', 32]];

const obj = Object.fromEntries(records);

> { name: 'da', age: 32}

Object.entries(obj);

> [['name','Mathew'], ['age', 32]];復(fù)制代碼

Symbol.prototype.description

只讀屬性,返回Symbol對象的可選描述:

Symbol('desc').toString();
> "Symbol(desc)"

Symbol('desc').description;  
> "desc"

Symbol('').description;      
> ""

Symbol().description;
> undefined復(fù)制代碼

以上是JavaScript與ES的重要知識點(diǎn)有哪些的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI