欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ES6所改良的javascript“缺陷”問題

 更新時(shí)間:2016年08月23日 10:17:14   作者:Bigdots  
這篇文章主要介紹了ES6所改良的javascript“缺陷”問題的相關(guān)資料,需要的朋友可以參考下

塊級(jí)作用域

ES5沒有塊級(jí)作用域,只有全局作用域和函數(shù)作用域,由于這一點(diǎn),變量的作用域甚廣,所以一進(jìn)入函數(shù)就要馬上將它創(chuàng)建出來。這就造成了所謂的變量提升。

ES5的“變量提升”這一特性往往一不小心就會(huì)造成一下錯(cuò)誤:

1.內(nèi)層變量覆蓋外層變量

var tmp = new Date();
function f() {
console.log(tmp);
if (false) { //執(zhí)行則undefined
var tmp = "hello world";
}
}

2.變量泄露,成為全局變量

var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5

往常我們往往是使用閉包來解決這一問題的(比如自執(zhí)行函數(shù))?,F(xiàn)在,基于這一問題,ES6增加了塊級(jí)作用域,所以不再需要自執(zhí)行函數(shù)了。

let 和 const

ES6是是向后兼容的,而保持向后兼容性意味著永不改變JS代碼在Web平臺(tái)上的行為,所以var創(chuàng)建的變量其作用域依舊將會(huì)是全局作用域和函數(shù)作用域。這樣以來,即使擁有了塊級(jí)作用域,也無法解決ES5的“變量提升”問題。所以,這里ES6新增了倆個(gè)新關(guān)鍵詞:let和const。

1.let

“l(fā)et是更完美的var”,它有著更好的作用域規(guī)則。

2.const

const聲明一個(gè)只讀的常量。一旦聲明,常量的值就不能改變,但const聲明的對(duì)象可以有屬性變化(對(duì)象凍結(jié)Object.freeze)

const a = [];
a.push('Hello'); // 可執(zhí)行
a = ['Dave']; // 報(bào)錯(cuò)

也可以使用Object.freeze將對(duì)象凍結(jié)

const foo = Object.freeze({});
// 常規(guī)模式時(shí),下面一行不起作用;
// 嚴(yán)格模式時(shí),該行會(huì)報(bào)錯(cuò)
foo.prop = 123;//

使用let和const:

•變量只在聲明所在的塊級(jí)作用域內(nèi)有效

•變量聲明后方可使用(暫時(shí)性死區(qū))

•不能重復(fù)定義變量

•聲明的全局變量,不屬于全局對(duì)象的屬性

var a = 1;
window.a // 1
let b = 1;
window.b // undefined

this關(guān)鍵字

我們知道,ES5函數(shù)中的this指向的是運(yùn)行時(shí)所在的作用域。比如

function foo() {
setTimeout(function(){
console.log('id:', this.id);
}, 100);
}
var id = 21;
foo.call({id:42});//id: 21

在這里,我聲明了一個(gè)函數(shù)foo,其內(nèi)部為一個(gè)延遲函數(shù)setTimeout,每隔100ms打印一個(gè)this.id。我們通過foo.call({id:42})來調(diào)用它,并且為這個(gè)函數(shù)設(shè)定作用域。它真正執(zhí)行要等到100毫秒后,由于this指向的是運(yùn)行時(shí)所在的作用域,所以這里的this就指向了全局對(duì)象window,而不是函數(shù)foo。這里:

•使用call來改變foo的執(zhí)行上下文,使函數(shù)的執(zhí)行上下文不再是window,從而來辨別setTimeout中的this指向

•setTimeout方法掛在window對(duì)象下,所以其this指向執(zhí)行時(shí)所在的作用域——window對(duì)象。

超時(shí)調(diào)用的代碼都是在全局作用域中執(zhí)行的,因此函數(shù)中this 的值在非嚴(yán)格模式下指向window 對(duì)象,在嚴(yán)格模式下是undefined --《javascript高級(jí)程序設(shè)計(jì)》

為了解決這一問題,我們往常的做法往往是將this賦值給其他變量:

function foo() {var that = this;
setTimeout(function(){
console.log('id:', that.id);
}, 100);
}
var id = 21;
foo.call({id:42});//id: 42

而現(xiàn)在ES6推出了箭頭函數(shù)解決了這一問題。

箭頭函數(shù)

標(biāo)識(shí)符=> 表達(dá)式

var sum = (num1, num2) => { return num1 + num2; }
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};

•如果函數(shù)只有一個(gè)參數(shù),則可以省略圓括號(hào)

•如果函數(shù)只有一條返回語句,則可以省略大括號(hào)和return

•如果函數(shù)直接返回一個(gè)對(duì)象,必須在對(duì)象外面加上括號(hào)。(因?yàn)橐粋€(gè)空對(duì)象{}和一個(gè)空的塊 {} 看起來完全一樣。所以需要用小括號(hào)包裹對(duì)象字面量。)

針對(duì)this關(guān)鍵字的問題,ES6規(guī)定箭頭函數(shù)中的this綁定定義時(shí)所在的作用域,而不是指向運(yùn)行時(shí)所在的作用域。這一以來,this指向固定化了,從而有利于封裝回調(diào)函數(shù)。

function foo() {var that = this;
setTimeout(()=>{
console.log('id:', that.id);
}, 100);
} 
var id = 21;
foo.call({id:42});//id: 42

注意:箭頭函數(shù)this指向的固定化,并不是因?yàn)榧^函數(shù)內(nèi)部有綁定this的機(jī)制,實(shí)際原因是箭頭函數(shù)根本沒有自己的this。而箭頭函數(shù)根本沒有自己的this,其內(nèi)部的this也就是外層代碼塊的this。這就導(dǎo)致了其:

•不能用作構(gòu)造函數(shù)

•不能用call()、apply()、bind()這些方法去改變this的指向

類與繼承

傳統(tǒng)ECMAScript沒類的概念,它描述了原型鏈的概念,并將原型鏈作為實(shí)現(xiàn)繼承的主要方法。其基本思想是利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法。而實(shí)現(xiàn)這一行為的傳統(tǒng)方法便是通過構(gòu)造函數(shù):

function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

在這里,構(gòu)造函數(shù)Point會(huì)有一個(gè)原型對(duì)象(prototype),這個(gè)原型對(duì)象包含一個(gè)指向Point的指針(constructor),而實(shí)例p包含一個(gè)指向原型對(duì)象的內(nèi)部指針(prop)。所以整個(gè)的繼承是通過原型鏈來實(shí)現(xiàn)的。詳情可見我的這篇文章:javascript中的prototype和constructor

class

ES6提供了更接近傳統(tǒng)語言的寫法,引入了Class(類)這個(gè)概念,作為對(duì)象的模板。通過class關(guān)鍵字,可以定義類。但是類只是基于原型的面向?qū)ο竽J降恼Z法糖。對(duì)于class的引入,褒貶不一,很多人認(rèn)為它反而是一大缺陷,但對(duì)我來說,這是一個(gè)好的語法糖,因?yàn)橥5脑玩溊^承的方式往往能把我繞那么一會(huì)兒。

//定義類
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var p = new Point(1, 2);

•類里面有一個(gè)constructor方法,它是類的默認(rèn)方法,通過new命令生成對(duì)象實(shí)例時(shí),自動(dòng)調(diào)用該方法。一個(gè)類必須有constructor方法,如果沒有顯式定義,一個(gè)空的constructor方法會(huì)被默認(rèn)添加。

•constructor方法中的this關(guān)鍵字代表實(shí)例對(duì)象,

•定義“類”的方法(如上例的toString)的時(shí)候,前面不需要加上function這個(gè)關(guān)鍵字,直接把函數(shù)定義放進(jìn)去了就可以了。另外,方法之間不需要逗號(hào)分隔,加了會(huì)報(bào)錯(cuò)。

•使用的時(shí)候,也是直接對(duì)類使用new命令,跟構(gòu)造函數(shù)的用法完全一致

•類的所有方法都定義在類的prototype屬性上面

class的繼承——extend

Class之間可以通過extends關(guān)鍵字實(shí)現(xiàn)繼承,這比ES5的通過修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多。

class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 調(diào)用父類的constructor(x, y)
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // 調(diào)用父類的toString()
}
}

•super關(guān)鍵字,作為函數(shù)調(diào)用時(shí)(即super(...args)),它代表父類的構(gòu)造函數(shù);作為對(duì)象調(diào)用時(shí)(即super.prop或super.method()),它代表父類。在這里,它表示父類的構(gòu)造函數(shù),用來新建父類的this對(duì)象。

•子類必須在constructor方法中調(diào)用super方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)。這是因?yàn)樽宇悰]有自己的this對(duì)象,而是繼承父類的this對(duì)象,然后對(duì)其進(jìn)行加工。如果不調(diào)用super方法,子類就得不到this對(duì)象。

模塊化

歷史上,JavaScript一直沒有模塊(module)體系,無法將一個(gè)大程序拆分成互相依賴的小文件,再用簡單的方法拼裝起來,這對(duì)開發(fā)大型的、復(fù)雜的項(xiàng)目形成了巨大障礙。為了適應(yīng)大型模塊的開發(fā),社區(qū)制定了一些模塊加載方案,比如CMD和AMD。

ES6的模塊化寫法:

import { stat, exists, readFile } from 'fs';

上面代碼的實(shí)質(zhì)是從fs模塊加載3個(gè)方法,其他方法不加載。這種加載稱為“編譯時(shí)加載”,即ES6可以在編譯時(shí)就完成模塊加載,效率要比CommonJS模塊的加載方式高。當(dāng)然,這也導(dǎo)致了沒法引用ES6模塊本身,因?yàn)樗皇菍?duì)象。

模塊功能主要由兩個(gè)命令構(gòu)成:

•export

用于規(guī)定模塊的對(duì)外接口,對(duì)外的接口,必須與模塊內(nèi)部的變量建立一一對(duì)應(yīng)關(guān)系。

// 寫法一
export var m = 1;
//錯(cuò)誤
export 1;
// 寫法二
var m = 1;
export {m};
//錯(cuò)誤
export m;
// 寫法三 重命名
var n = 1;
export {n as m};

•import

用于輸入其他模塊提供的功能,它接受一個(gè)對(duì)象(用大括號(hào)表示),里面指定要從其他模塊導(dǎo)入的變量名(也可以使用*號(hào)整體加載)

字符串插值

在javascript的開發(fā)中,我們常常需要這樣來輸出模板:

function sayHello(name){
return "hello,my name is "+name+" I am "+getAge(18);
}
function getAge(age){
return age;
}
sayHello("brand") //"hello,my name is brand I am 18"

我們需要使用+來連接字符串和變量(或者表達(dá)式)。例子比較簡單,所以看上去無傷大雅,但是一旦在比較復(fù)雜的情況下,就會(huì)顯得相當(dāng)繁瑣不方便,這一用法也讓我們不厭其煩。對(duì)此,ES6引入了模板字符串,可以方便優(yōu)雅地將 JS 的值插入到字符串中。

模板字符串

對(duì)于模板字符串,它:

•使用反引號(hào)``包裹;

•使用${}來輸出值;

•${}里的內(nèi)容可以是任何 JavaScript 表達(dá)式,所以函數(shù)調(diào)用和算數(shù)運(yùn)算等都是合法的;

•如果一個(gè)值不是字符串,它將被轉(zhuǎn)換為字符串;

•保留所有的空格、換行和縮進(jìn),并輸出到結(jié)果字符串中(可以書寫多行字符串)

•內(nèi)部使用反引號(hào)和大括號(hào)需要轉(zhuǎn)義,轉(zhuǎn)義使用反斜杠\

對(duì)于上面的例子,模板字符串的寫法是:

function sayHello(name){
return `hello,my name is ${name} I am ${getAge(18)}`;
}
function getAge(age){
return age;
}
sayHello("brand") //"hello,my name is brandI am 18"

嚴(yán)格模式

嚴(yán)格模式的目標(biāo)之一是允許更快地調(diào)試錯(cuò)誤。幫助開發(fā)者調(diào)試的最佳途徑是當(dāng)確定的問題發(fā)生時(shí)拋出相應(yīng)的錯(cuò)誤(throw errors when certain patterns occur),而不是悄無聲息地失敗或者表現(xiàn)出奇怪的行為(非嚴(yán)格模式下經(jīng)常發(fā)生)。嚴(yán)格模式下的代碼會(huì)拋出更多的錯(cuò)誤信息,能幫助開發(fā)者很快注意到一些必須立即解決的問題。在 ES5 中, 嚴(yán)格模式是可選項(xiàng),但是在 ES6 中,許多特性要求必須使用嚴(yán)格模式,這個(gè)習(xí)慣有助于我們書寫更好的 JavaScript。

以上所述是小編給大家介紹的ES6所改良的javascript“缺陷”問題,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • js實(shí)現(xiàn)動(dòng)態(tài)增加文件域表單功能

    js實(shí)現(xiàn)動(dòng)態(tài)增加文件域表單功能

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)動(dòng)態(tài)增加文件域表單功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • JS實(shí)現(xiàn)的緩沖運(yùn)動(dòng)效果示例

    JS實(shí)現(xiàn)的緩沖運(yùn)動(dòng)效果示例

    這篇文章主要介紹了JS實(shí)現(xiàn)的緩沖運(yùn)動(dòng)效果,涉及JavaScript數(shù)值運(yùn)算與時(shí)間函數(shù)相關(guān)使用技巧,需要的朋友可以參考下
    2018-04-04
  • 微信小程序JSON配置文件詳細(xì)講解作用

    微信小程序JSON配置文件詳細(xì)講解作用

    JSON是一種數(shù)據(jù)格式,在實(shí)際開發(fā)中,JSON總是以配置文件的形式出現(xiàn)。小程序項(xiàng)目中也不例外:通過不同的Json配置文件,可以對(duì)小程序項(xiàng)目進(jìn)行不同級(jí)別的配置
    2022-10-10
  • 基于WebUploader的文件上傳js插件

    基于WebUploader的文件上傳js插件

    這篇文章主要為大家詳細(xì)介紹了基于WebUploader的文件上傳js插件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • this,this,再次討論javascript中的this,超全面(經(jīng)典)

    this,this,再次討論javascript中的this,超全面(經(jīng)典)

    在JavaScript中,this 的概念比較復(fù)雜。除了在面向?qū)ο缶幊讨?,this 還是隨處可用的。這篇文章介紹了javascript中的this相關(guān)知識(shí),對(duì)javascript this相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • 微信小程序swiper左右擴(kuò)展各顯示一半代碼實(shí)例

    微信小程序swiper左右擴(kuò)展各顯示一半代碼實(shí)例

    這篇文章主要介紹了微信小程序swiper左右擴(kuò)展各顯示一半代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • JavaScript實(shí)現(xiàn)事件總線(Event?Bus)的方法詳解

    JavaScript實(shí)現(xiàn)事件總線(Event?Bus)的方法詳解

    Event?Bus?事件總線,通常作為多個(gè)模塊間的通信機(jī)制,相當(dāng)于一個(gè)事件管理中心。本文將介紹如何在JavaScript中實(shí)現(xiàn)事件總線,需要的可以參考一下
    2022-05-05
  • 老生常談javascript?hash的使用

    老生常談javascript?hash的使用

    在javascript中,hash指的是哈希表,是一種根據(jù)關(guān)鍵字直接訪問內(nèi)存存儲(chǔ)位置的數(shù)據(jù)結(jié)構(gòu),hash就是一個(gè)賦值的方法,但實(shí)際用的并不需要太復(fù)雜,能用的就一點(diǎn)點(diǎn),寫法也非常簡單,hash有多種寫法,本文給大家介紹javascript?hash使用,感興趣的朋友一起看看吧
    2023-10-10
  • 奇妙的js

    奇妙的js

    奇妙的js...
    2007-09-09
  • js實(shí)現(xiàn)二代身份證號(hào)碼驗(yàn)證詳解

    js實(shí)現(xiàn)二代身份證號(hào)碼驗(yàn)證詳解

    本文給大家分享一段超級(jí)全面的二代身份證號(hào)碼驗(yàn)證程序,由JS編寫而成,可以校驗(yàn)身份證的地址碼、出生日期碼、順序碼和數(shù)字校驗(yàn)碼。是身份證去偽存真的一大利器。
    2014-11-11

最新評(píng)論