成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES5學(xué)習(xí)(上)

HackerShell / 3324人閱讀

摘要:對象是一個值超出有效范圍時發(fā)生的錯誤。包括返回原數(shù)組包括數(shù)組對象函數(shù)可以用來判斷變量是否為對象數(shù)組對象函數(shù)構(gòu)造函數(shù)與直接賦值是等價的。只適用于,數(shù)組不適用通過可以看出一個值到底是什么類型,其中返回值的第二個值表示該值的構(gòu)造函數(shù)。

這是ES5的入門篇教程的筆記,網(wǎng)址:JavaScript教程,以下內(nèi)容中黑體表示大標(biāo)題,還有一些重點;斜體表示對于自身,還需要下功夫?qū)W習(xí)的內(nèi)容。這里面有一些自己的見解,所以若是發(fā)現(xiàn)問題,歡迎指出~

數(shù)據(jù)類型
只有var存在變量提升,let不存在變量提升。
js內(nèi)部都是以64位浮點數(shù)的形式存儲(64位表示精度),整數(shù)也如此,所以1.0和1是相同的一個數(shù),1.0===1.
JavaScript 語言的底層根本沒有整數(shù)。由于浮點數(shù)不是精確的值,所以涉及小數(shù)的比較和運(yùn)算都不是很準(zhǔn)確。
NaN === NaN 用于判斷是否是NaN。

關(guān)于函數(shù)
函數(shù)執(zhí)行時所在的作用域,是定義時的作用域,而不是調(diào)用時所在的作用域
函數(shù)參數(shù)不是必須的,JavaScript允許省略參數(shù)(與其他語言不同?。。。?,函數(shù)的length屬性與實際傳入的參數(shù)個數(shù)無關(guān),只反映函數(shù)預(yù)期傳入的參數(shù)個數(shù),如下:

function f(a, b) {
    return a;
}

f(1, 2, 3) // 1
f(1) // 1
f() // undefined
f(, 1) // SyntaxError: Unexpected token ,...
f(undefined, 1) // undefined 省略考前的參數(shù),只有顯式傳入undefined

f.length // 2

函數(shù)參數(shù)如果是原始類型的值(數(shù)值、字符串、布爾值),傳遞方式是傳值傳遞,也就是說,在函數(shù)體內(nèi)修改參數(shù)值,不會影響到函數(shù)外部;但是,如果是復(fù)合類型(數(shù)組、對象、其他函數(shù)),傳遞方式是傳址傳遞,將會影響到原始值(如果函數(shù)內(nèi)部修改的內(nèi)容,不是參數(shù)對象的某個屬性,而是替換掉整個參數(shù),這是不會影響到原始值)。

var p = 2;
function f(p) {
    p = 3; // 這只是一個拷貝
}
f(p);
p // 2

var obj = { p: 1 };
function f(o) {
    o.p = 2;
}
f(obj);
obj.p // 2

var obj = [1, 2, 3];
function f(o) {
  o = [2, 3, 4]; // 形參o的值指向的是實參obj的地址,重新對o賦值后,o會指向另一個地址,而obj指向的原地址比那個沒有發(fā)生改變,所以obj不會變化。
}
f(obj);
obj // [1, 2, 3] 

由于JavaScript允許函數(shù)有不定數(shù)目的參數(shù),可以通過arguments對象讀取所有參數(shù),在嚴(yán)格模式下,arguments很多方法都是受到限制的;arguments很像數(shù)組,但它是一個對象(arguments是偽數(shù)組)。

什么是閉包?就是在函數(shù)的內(nèi)部,再定義一個函數(shù),用來得到函數(shù)內(nèi)部的局部變量。閉包兩個最大用處有兩個,一個是可以讀取函數(shù)內(nèi)部的變量,另一個是讓這些變量始終保持在內(nèi)存中,也就是閉包可以使得它的誕生環(huán)境一直存在(這個作用有點不理解,需要去理解系統(tǒng)垃圾回收機(jī)制)。閉包還可以封裝對象的私有屬性和私有方法,如下(跟Java類似):

function Person(name) {
  var _age;
  function setAge(n) {
    _age = n;
  }
  function getAge() {
    return _age;
  }
  return {
    name: name,
    getAge: getAge,
    setAge: setAge
  };
}

var p1 = Person("張三");
p1.setAge(25);
p1.getAge() // 25

注: 外層函數(shù)每次運(yùn)行,都會生成一個新的閉包,而這個閉包又會保留外層函數(shù)的內(nèi)部變量,所以內(nèi)存消耗很大。因此不能濫用閉包,否則會造成網(wǎng)頁的性能問題。

在JavaScript中,圓括號()是一種運(yùn)算符(以前知道圓括號是執(zhí)行函數(shù)的意思,但它算運(yùn)算符還真的不知道,所以人丑還是要多讀書),跟在函數(shù)名之后,表示調(diào)用該函數(shù),比如,print()就是表示調(diào)用print函數(shù)。不能再函數(shù)的定義之后加上圓括號,會產(chǎn)生語法錯誤,因為JavaScript規(guī)定function關(guān)鍵字出現(xiàn)在行首,一律解釋成語句,而不是表達(dá)式,如下:

function(){ /* code */ }();
// SyntaxError: Unexpected token ...

// 以下兩種方法都可以馬上執(zhí)行,這叫做“立即調(diào)用的函數(shù)表達(dá)式”,簡稱IIFE
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();

關(guān)于數(shù)組
JavaScript語言規(guī)定,對象的鍵名一律為字符串,所以數(shù)組的鍵名其實也是字符串,之所以可以用數(shù)值讀取,是因為非字符串的鍵名會被轉(zhuǎn)為字符串(這個以前還真不知道)。
對象中有兩種去讀取成員的方法:點結(jié)構(gòu)(object.key)和方括號結(jié)構(gòu)(object[key])。但是,對于數(shù)值的鍵名,不能使用點結(jié)構(gòu)。因為arr.0的寫法不合法,多帶帶的數(shù)值不能作為標(biāo)識符,所以數(shù)組成員只能用方括號arr[0]表示(方括號是運(yùn)算符,可以接受數(shù)值)。
清空/刪除數(shù)組,可以用length屬性試試哦;當(dāng)然如果設(shè)置length大于數(shù)組個數(shù)時,讀取新增的位置都會返回undefined。
for..in 用于對象,不推薦用于數(shù)組(因為數(shù)組也是對象,可以用非數(shù)字鍵加鍵名,for...in會遍歷所有數(shù)字鍵和非數(shù)字鍵,數(shù)組遍歷肯定遍歷的是數(shù)字鍵);for()循環(huán)、while循環(huán)用于數(shù)組。(en,這個我知道)

數(shù)組的空位和undifined不一樣,但是讀取到的卻是undefined,length屬性不過濾空位,但數(shù)組的forEach方法、for...in結(jié)構(gòu)、以及Object.keys方法進(jìn)行遍歷,空位都會被跳過。空位表示數(shù)組沒有這個元素,所以不會被遍歷;undefined表示數(shù)組有這個元素,但值為undefined,所以遍歷不會跳過。

var a = [, , ,];
a[1] // undefined

這里說的“類似數(shù)組的對象”,在其他地方看到過其他資料,叫做“偽數(shù)組”。
根本特征:具有l(wèi)ength屬性,但是length屬性不是動態(tài)值,不會隨著成員的變化而變化。(其他地方也提到過,arguments也是偽數(shù)組。)
變?yōu)檎嬲臄?shù)組,一是用slice,二時用call()。這兩個內(nèi)容看不懂,還需要努力!

運(yùn)算符
“重載”?。。∥抑辉贘ava里面聽到過函數(shù)重載,js里面運(yùn)算符竟然也有這種叫法,長知識了!什么叫“重載”呢?加法運(yùn)算符在運(yùn)行時決定,是執(zhí)行相加,還是執(zhí)行連接,也就是說,運(yùn)算子的不同,導(dǎo)致了不同的語法行為,這種行為成為“重載”。(只有加法運(yùn)算符才有這種操作,減法、除法和乘法都不會發(fā)生重載,因為其他的算術(shù)運(yùn)算符,有一個規(guī)則:所有運(yùn)算子一律轉(zhuǎn)為數(shù)值,再進(jìn)行相應(yīng)的數(shù)學(xué)運(yùn)算。)

指數(shù)運(yùn)算符‘**’,這是第一次遇見,以前都是用Math.pow()來求冪的?。?!
發(fā)現(xiàn)兩者最大的區(qū)別在于編譯是99**99編譯時計算,Math.pow(99, 99)運(yùn)行時計算,具體說明參考“常量折疊”優(yōu)化技巧
‘**’指數(shù)運(yùn)算符是右結(jié)合,而不是左結(jié)合,如下:

2 ** 3 **2
// 512 相當(dāng)于 2**(3 ** 2)

關(guān)于相等和嚴(yán)格相等,這里的解釋是最令人通俗易懂的?。?!
‘==’比較的是兩個值是否相等;‘===’表比較它們是否為“同一個值”?!巴粋€值”也就是不僅要比較他們的值,還要比較它們的類型。
NaN與任何值都不相等(包括自身),正0等于負(fù)0(為什么,想不通)。
復(fù)合類型的數(shù)據(jù)比較,比較的是它們是否指向同一個地址。
null和undefined與自身嚴(yán)格相等,與其他類型的值比較時,結(jié)果都為false,它們互相比較時結(jié)果為true。

NaN == NaN // false
+0 === -0 // true

{} === {} // false
{} == {} // false

undefined === undefined // true
null === null // true

false == null // false
false == undefined // false

0 == null // false
0 == undefined // false

undefined == null // true

二進(jìn)制位運(yùn)算符實際中并不常用,所以并不怎么熟悉,但是我發(fā)現(xiàn)了一個有趣的東西,那就是異或運(yùn)算符^。
平時互換兩個變量的值,一般的做法是引入一個臨時變量temp,用來作為中間變量,但如果熟悉異或運(yùn)算符,可以進(jìn)行如下操作:

let a = 10;
let b = 99;
a ^= b, b ^= a, a ^= b;
a // 99
b // 10

12.9 ^ 0 // 12 異或運(yùn)算也可以用來取整(“向下取整”,不能嚴(yán)格地說是向下取整)。
-12.9 ^ 0 // -12

數(shù)據(jù)類型轉(zhuǎn)換
強(qiáng)制轉(zhuǎn)換有三種Number()、String()和Boolean(),以前只會用Number(),不怎么常用后面兩種,常用toString()和!!代替前面兩個,也沒什么區(qū)別吧。
Number函數(shù)比parseInt函數(shù)嚴(yán)格很多,基本上只要有一個字符無法轉(zhuǎn)成數(shù)值,整個字符串就會被轉(zhuǎn)為NaN。parseInt逐個解析字符,而Number函數(shù)整體轉(zhuǎn)換字符串的類型。
關(guān)于Boolean(),除了undefined、null、0、NaN、"",五個值轉(zhuǎn)換結(jié)果為false,其他的值全部為true,包括空對象、空數(shù)組的轉(zhuǎn)換結(jié)果也為true。

parseInt("42 cats") // 42
Number("42 cats") // NaN

Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean("") // false
Boolean({}) // true
Boolean([]) // true

Boolean(false) // false
Boolean(new Boolean(false)) // true 因為這是一個對象

null轉(zhuǎn)為數(shù)值時為0,而undefined轉(zhuǎn)為數(shù)值時為NaN。

錯誤機(jī)制處理
每次出現(xiàn)報錯信息,都看不懂報錯的原因是為什么,終于可以讓我好好理解一下,因為什么原因會報錯了。
Error實例對象是最一般的錯誤類型,在它的基礎(chǔ)上,JavaScript還定義了其他6種錯誤對象,也就是說,存在Error的6個派生對象。
SyntaxError對象是解析代碼時發(fā)生的語法錯誤。
ReferenceError對象是引用一個不存在的變量時發(fā)生的錯誤。
RangeError對象是一個值超出有效范圍時發(fā)生的錯誤。
TypeError對象是變量或參數(shù)不是預(yù)期類型時發(fā)生的錯誤。
URIError對象是URI相關(guān)函數(shù)的參數(shù)不正確時拋出的錯誤。
EvalError對象是eval函數(shù)沒有被正確執(zhí)行時,拋出的錯誤,該錯誤類型已經(jīng)不再使用了,只是為了保證與以前代碼兼容,才繼續(xù)保留。

編程規(guī)范
不使用分號的三種情況
1、for和while循環(huán),注:do…while循環(huán)是有分號的;
2、分支語句:if,switch,try
3、函數(shù)的聲明語句,注:函數(shù)表達(dá)式仍然要使用分號。

for( ; ; ) {
}

while (true) {
} // 沒有分號

do {
    a--;
} while(a > 0); // 有分號 

if (true) {
}

switch () {
}

try {
} catch {
}

function f() {
} // 沒有分號
let f = function f() {
}; // 有分號

有一個重大的發(fā)現(xiàn),竟然可以用對象結(jié)果代替switch…case結(jié)構(gòu)?。?!

function doAction(action) {
    switch (action) {
        case "hack":
            return "hack";
        case "slash":
            return "slash";
        default:
            throw new Error("Invalid action.");
    }
}

// 變身后
function doAction(action) {
    let actions = {
        "hack": function () {
            return "hack";
        },
        "slash": function () {
            return "slash";
        }
    };
    if (typeof actions[action] !== "function") {
        throw new Error("Invalid action.");
    }
    
    return actions[action]();
}

語法專題
真是沒想到console.log方法還支持占位符,可以像C語言一樣用于輸出不同類型的數(shù)據(jù)。
占位符有以下幾種:
%s 字符串
%d 整數(shù)
%i 整數(shù)
%f 浮點數(shù)
%o 對象的連接
%c CSS格式字符串(這個是最令我好奇的)

其他的有關(guān)console方法,感覺用處不是很大,其中有個console.count()感覺還是會用到的,count方法用于計數(shù),輸出它被調(diào)用了多少次。

function greet(user) {
    console.count();
    return "hi " + user;
}

greet("bob")
// default: 1
// "hi bob"

greet("alice")
// default: 2
// "hi alice"

標(biāo)準(zhǔn)庫
Object對象的原生方法分成兩類:
1)Object本身的方法(又稱為“靜態(tài)方法”):直接定義在Object對象的方法;
2)Object的實例方法:定義在Object原型對象Object.prototype上的方法,它可以被Obejct實例直接使用。

Object.print = function (o) { console.log(o) }; // 這個Object對象本身的方法,print方法直接定義在Object對象上
Object.prototype.print = function () {
    console.log(this);
};

let obj = new Object();
obj.print() // Object  凡是定義在Object.prototype對象上面的屬性和方法,將被所有實例對象共享。

Object本身是一個函數(shù),如果參數(shù)是原始類型的值,Object方法將其轉(zhuǎn)為對應(yīng)的包裝對象的實例;如果Object方法的參數(shù)是一個對象,它總是返回該對象,即不用轉(zhuǎn)換。

let obj = Object(1);
obj instanceof Object // true
obj instanceof Number // true 包括number、string、boolean

let arr = [];
let obj = Object(arr); // 返回原數(shù)組
obj === arr // true 包括數(shù)組、對象、函數(shù)

function isObject(value) {
    return value === Obejct(value);
} // 可以用來判斷變量是否為對象(數(shù)組、對象、函數(shù))

Object構(gòu)造函數(shù)與直接賦值是等價的。

var o1 = {a: 1};
var o2 = new Object(o1); // 兩個對象指針指向同一個地址。
var o3 = new Object({a: 1}); // 不能這樣賦值哦,這樣賦值,重新分配了一個地址,就是一個全新的對象。
o1 === o2 // true 只適用于Object,數(shù)組不適用
o1 === o3 // false

var obj = new Object(123);
obj instanceof Number // true

通過Object.prototype.toString可以看出一個值到底是什么類型,其中返回值的第二個值表示該值的構(gòu)造函數(shù)。實例對象可能會自定義toString方法,覆蓋掉Object.propotype.toString方法,所以最要直接用Object.prototype.toString方法,并通過函數(shù)的call方法,可以在任意上調(diào)用這個方法。

Object.prototype.toString.call(2) // "[object Number]"
Object.prototype.toString.call("") // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(Math) // "[object Math]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"

// **比typeof運(yùn)算符更準(zhǔn)確的類型判斷函數(shù)**
var type = function (o){
  var s = Object.prototype.toString.call(o); // *這里的正則表達(dá)式還需下點功夫,學(xué)會手動寫正則*
  return s.match(/[object (.*?)]/)[1].toLowerCase();
};

type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"

emmm接下來的屬性描述,平時不怎么接觸,對這一塊也很陌生,以后要多看看?。?!
for...in循環(huán):只有“可遍歷”的屬性,才會被for...in循環(huán)遍歷,包括繼承的屬性。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/104859.html

相關(guān)文章

  • 零基礎(chǔ)的前端開發(fā)初學(xué)者應(yīng)如何系統(tǒng)地學(xué)習(xí)?

    摘要:在有了基礎(chǔ)之后,進(jìn)一步學(xué)習(xí)內(nèi)容包括框架。前端學(xué)習(xí)交流群禁止閑聊,非喜勿進(jìn)。代碼提交前必須做的三個事情檢查所有變更跑一邊單元測試手動運(yùn)行一遍所有 網(wǎng)站開發(fā)開發(fā)大致分為前端和后端,前端主要負(fù)責(zé)實現(xiàn)視覺和交互效果,以及與服務(wù)器通信,完成業(yè)務(wù)邏輯。其核心價值在于對用戶體驗的追求。可以按如下思路學(xué)習(xí)系統(tǒng)學(xué)習(xí): 基礎(chǔ)知識: html + css 這部分建議在?w3school 在線教程上學(xué)習(xí),邊...

    JouyPub 評論0 收藏0
  • 零基礎(chǔ)的前端開發(fā)初學(xué)者應(yīng)如何系統(tǒng)地學(xué)習(xí)

    摘要:在有了基礎(chǔ)之后,進(jìn)一步學(xué)習(xí)內(nèi)容包括框架。前端學(xué)習(xí)交流群禁止閑聊,非喜勿進(jìn)。代碼提交前必須做的三個事情檢查所有變更跑一邊單元測試手動運(yùn)行一遍所有 網(wǎng)站開發(fā)開發(fā)大致分為前端和后端,前端主要負(fù)責(zé)實現(xiàn)視覺和交互效果,以及與服務(wù)器通信,完成業(yè)務(wù)邏輯。其核心價值在于對用戶體驗的追求??梢园慈缦滤悸穼W(xué)習(xí)系統(tǒng)學(xué)習(xí): 基礎(chǔ)知識: html + css 這部分建議在?w3school 在線教程上學(xué)習(xí),邊...

    funnyZhang 評論0 收藏0
  • 前端基礎(chǔ)進(jìn)階(十四):es6常用基礎(chǔ)合集

    摘要:在繼承的構(gòu)造函數(shù)中,我們必須如上面的例子那么調(diào)用一次方法,它表示構(gòu)造函數(shù)的繼承,與中利用繼承構(gòu)造函數(shù)是一樣的功能。 showImg(https://segmentfault.com/img/remote/1460000009078532); 在實際開發(fā)中,ES6已經(jīng)非常普及了。掌握ES6的知識變成了一種必須。盡管我們在使用時仍然需要經(jīng)過babel編譯。 ES6徹底改變了前端的編碼風(fēng)格,...

    Ryan_Li 評論0 收藏0
  • 重新認(rèn)識JavaScript面向?qū)ο? 從ES5到ES6

    摘要:基于原型的面向?qū)ο笤诨谠偷恼Z言中如并不存在這種區(qū)別它只有對象不論是構(gòu)造函數(shù),實例,原型本身都是對象。允許動態(tài)地向單個的對象或者整個對象集中添加或移除屬性。為了解決以上兩個問題,提供了構(gòu)造函數(shù)創(chuàng)建對象的方式。 showImg(https://segmentfault.com/img/remote/1460000013229218); 一. 重新認(rèn)識面向?qū)ο?1. JavaScript...

    VishKozus 評論0 收藏0
  • 重新認(rèn)識JavaScript面向?qū)ο? 從ES5到ES6

    摘要:基于原型的面向?qū)ο笤诨谠偷恼Z言中如并不存在這種區(qū)別它只有對象不論是構(gòu)造函數(shù),實例,原型本身都是對象。允許動態(tài)地向單個的對象或者整個對象集中添加或移除屬性。為了解決以上兩個問題,提供了構(gòu)造函數(shù)創(chuàng)建對象的方式。 showImg(https://segmentfault.com/img/remote/1460000013229218); 一. 重新認(rèn)識面向?qū)ο?1. JavaScript...

    用戶83 評論0 收藏0

發(fā)表評論

0條評論

HackerShell

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<