国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

你需要知道的 javascript 的細節

Airy / 3110人閱讀

摘要:代碼示例語法和方法類似,不同的是,傳入調用函數的參數變成以數組的形式傳入,即改造上面的示例就是方法用于將函數體內的綁定到某個對象,然后返回一個新函數。類型包裝對象數值字符串布爾值在一定條件下,也會自動轉為對象,也就是原始類型的包裝對象。

現在的前端框架層出不窮,3個月就要重新入門一次前端的現狀,讓我們來不及學好基礎就開始上手框架。常常就因為這樣,我們會很快到達基礎基礎技術瓶頸,基礎是所有技術的核心,在跳槽季重新溫故了一遍 javascript 基礎,有收獲,整理出來分享給大家。
對象 變量可以當對象使用

javascript 中所有的變量都可以當做對象使用,除了undefinednull ,我們測試下

false.toString() // "false"

[1,2,3].toString() //"1,2,3"

1..toString() //"1"

({a:"33"}).toString() //"[object Object]"
undefined.toString() //Uncaught TypeError

null.toString()   //Uncaught TypeError

數值和對象雖然能調用 toString 方法,但是在寫法上需要注意下

number 調用時不能直接數值后面直接調用toString 方法,因為 js 會將點運算符解析為數值的小數點

1.toString() //Uncaught SyntaxError

1..toString() //"1"

對象直接調用toString 方法時,需要用小括號包裹起來,不然js 會將對象的花括號識別成塊,從而報錯

{a:"33"}.toString()  // Uncaught SyntaxError

({a:"33"}).toString() // "[object Object]"
對象刪除屬性
刪除對象的屬性唯一的方法是使用 delete 操作符,設置元素屬性為 undefined 或則 null 并不能真正刪除,只是移除了屬性和值的關聯
var test = {
    name:"bbt",
    age:"18",
    love:"dog"
}

test.name = undefined
test.age = null
delete test.love

for (var i in test){
  console.log(i+":"+test[i])
}

運行結果

name:undefined
age:null
undefined

只有 love 被正則刪除,nameage 還是能被遍歷到

構造函數
javascript 中,通過關鍵字 new 調用的函數就被認為是構造函數,我們可以通過構造函數創建對象實例

但是在使用過程中你一定發現了,每實例化一個對象,都會在實例對象上創造構造函數的方法和屬性。倘若創建的實例比較多,重復創建同一個方法去開辟內存空間就會顯得十分浪費,我們可以通過把被經常復用的方法放在原型鏈上。

原型繼承
javascript 和一些我們所了解的面向對象編程的語言不太一樣,在 es6 語法以前,我們是通過原型鏈來實現方法和屬性的繼承
function Child(){
  this.name = "bbt"
}

Child.prototype = {
    title:"baba",
    method: function() {}
};

function Grandson(){}

//設置 Grandson 的 prototype 為 Child 的實例
Grandson.prototype = new Child()

//為 Grandson 的原型添加添加屬性 age
Grandson.prototype.age = 40

// 修正 Grandson.prototype.constructor 為 Grandson 本身
Grandson.prototype.constructor = Grandson;

var xiaomin = new Grandson()

//原型鏈如下
xiaomin // Grandson的實例
    Grandson.prototype // Child的實例
         Grandson.prototype //{title:"baba",...}
            Object.prototype
                {toString: ... /* etc. */};

對象的屬性查找,javascript 會在原型鏈上向上查找屬性,直到查到 原型鏈頂部,所以,屬性在原型鏈的越上端,查找的時間會越長,查找性能和復用屬性方面需要開發者自己衡量下。

獲取自身對象屬性

hasOwnProperty 方法能夠判斷一個對象是否包含自定義屬性,而不是在原型鏈上的屬性

var test = {hello:"123"}

Object.prototype.name = "bbt"

test.name  //"bbt"
test.hasOwnProperty("hello") //true
test.hasOwnProperty("name") //false

for in 循環可以遍歷對象原型鏈上的所有屬性,如此我們將 hasOwnProperty 結合循環for in 能夠獲取到對象自定義屬性

var test = {hello:"222"}
Object.prototype.name = "bbt"

for(var i in test){
  console.log(i) // 輸出兩個屬性,hello ,name
}


for(var i in test){
  if(test.hasOwnProperty(i)){
    console.log(i)//只輸出 hello
  }
}

除了上面的方法,getOwnPropertyNames Object.keys 方法,能夠返回對象自身的所有屬性名,也是接受一個對象作為參數,返回一個數組,包含了該對象自身的所有屬性名。

var test = {hello:"222"}
Object.prototype.name = "bbt"

Object.keys(test) //["hello"]
Object.getOwnPropertyNames(test) //["hello"]

getOwnPropertyNamesObject.keys 的用法有什么區別呢

Object.keys方法只返回可枚舉的屬性,Object.getOwnPropertyNames 方法還返回不可枚舉的屬性名。

var a = ["Hello", "World"];

Object.keys(a) // ["0", "1"]

Object.getOwnPropertyNames(a) // ["0", "1", "length"]  // length 是不可枚舉屬性
函數 函數聲明的變量提升

我們通常會使用函數聲明或函數賦值表達式來定義一個函數,函數聲明和變量聲明一樣都存在提升的情況,函數可以在聲明前調用,但是不可以在賦值前調用

函數聲明

foo(); // 正常運行,因為foo在代碼運行前已經被創建
function foo() {}

函數表達式

foo; // "undefined"
foo(); // 出錯:TypeError
var foo = function() {};

變量提升是在代碼解析的時候進行的,foo() 方法調用的時候,已經在解析階段將 foo 定義過了。賦值語句只在代碼運行時才進行,所以在賦值前調用會報錯

一種比較少用的函數賦值操作,將命名函數賦值給一個變量,此時的函數名只對函數內部可見

var test = function foo(){
  console.log(foo) //正常輸出
}

console.log(foo) //Uncaught ReferenceError
this 的工作原理
javascript 中 ,this 是一個比較難理解的點,不同的調用環境會導致 this 的不同指向,但是唯一不變的是 this 總是指向一個對象

簡單的說,this 就是屬性和方法當前所在的對象(函數執行坐在的作用域),平時使用的 this 的情況可以大致分為5種

調用方式 指向
1. 全局范圍調用 指向 window 全局對象
2. 函數調用 指向 window 全局變量
3. 對象的方法調用 指向方法調用的對象
4. 構造函數調用 指向構造函數創建的實例
5. 通過,call ,apply ,bind 顯示的指定 this指向 和傳參有關

Function.call

語法:function.call(thisArg, arg1, arg2, …),thisArg表示希望函數被調用的作用域,arg1, arg2, …表示希望被傳入函數額參數 , 如果參數為空、nullundefined,則默認傳入全局對象。

代碼示例

var name = "xiaomin"
var test = {name : "bbt"}

function hello( _name ){
  _name ?console.log(this.name,_name): console.log(this.name)
}

hello() //xiaomin
hello.call(test) //bbt
hello.call(test,"xiaohong") //bbt xiaohong
hello.call() //xiaomin
hello.call(null) //xiaomin
hello.call(undefined) //xiaomin

Function.apply

語法和call 方法類似,不同的是,傳入調用函數的參數變成以數組的形式傳入,即 func.apply(thisArg, [argsArray])

改造上面的示例就是

hello.apply(test,["xiaomin"])

Function.bind

bind方法用于將函數體內的this綁定到某個對象,然后返回一個新函數。
var d = new Date();
d.getTime()

var print = d.getTime; //賦值后 getTime 已經不指向 d 實例
print() // Uncaught TypeError

解決方法

var print = d.getTime.bind(d)

容易出錯的地方

容易出錯的地方,函數調用,this 總是指向 window 全局變量,所以在對象的方法里如果有函數的調用的話(閉包的情況),this 是會指向 全局對象的,不會指向調用的對象,具體示例如下

var name = "xiaomin"
var test = {
  name : "bbt"
}
test.method = function(){
  function hello(){
      console.log(this.name)
    }
    hello()
}

// 調用
test.method() // 輸出 xiaomin

如果需要將 this 指向調用的對象,可以將對象的 this 指向存儲起來,通常我們使用 that 變量來做這個存儲。改進之后的代碼

var name = "xiaomin"
var test = {
  name : "bbt"
}
test.method = function(){
  var that = this
  function hello(){
      console.log(that.name)
    }
    hello()
}

// 調用
test.method() // 輸出 bbt
閉包和引用
閉包我們可以理解成是在函數內部定義的函數

javascript 中,內部作用域可以訪問到外部作用域的變量,但是外部作用域不能訪問內部作用域,需要訪問的時候,我們需要通過創建閉包,來操作內部變量

function test(_count){
  var count = _count

  return {
    inc:function(){
      count++
    },
    get:function(){
      return count
    }
  }
}

var a = test(4)
a.get()//4
a.inc()
a.get()//5

閉包中常會出錯的面試題

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 0);
}

很多同學會覺得,上面的代碼會正常輸出0到9,但是實際是輸出十次10。遇到這個題目,除了閉包的概念要理解清楚,你還需要知道,setTimeout 內的代碼會被異步執行,代碼會先執行所有的同步代碼,即上面的這段代碼會先將 for 循環執行,此時 i 的值為 10,console.log(i) 一直引用著全局變量的 i 所以會輸出十次 10

改進代碼,我們在 for 循環里創建一個閉包,把循環自增的 i 作為參數傳入

for(var i = 0; i < 10; i++) {
    (function(e) {
        setTimeout(function() {
            console.log(e);
        }, 1000);
    })(i);
}
setTimeout && setInterval
javascript 是異步的單線程運行語言,其他代碼運行的時候可能會阻塞 setTimeout && setInterval 的運行
console.log(1)
setTimeout(function(){
  console.log(2)
}, 0);
console.log(3)

輸出結果: 1,3,2  //setTimeout 被阻塞

處理阻塞的方法是將setTimeoutsetInterval放在回調函數里執行

function test(){
      setTimeout(function(){
          console.log(2)
    }, 0);
}

setTimeoutsetInterval 被調用時會返回一個 ID 用來清除定時器

手工清除某個定時器

var id = setTimeout(foo, 1000);
clearTimeout(id);

清楚所有的定時器

var lastId = setTimeout(function(){
  console.log("11")
}, 0);

for(var i=0;i

獲取最后一個定時器的id,遍歷清除定時器,可以清除所有的定時器。

類型 包裝對象
數值、字符串、布爾值——在一定條件下,也會自動轉為對象,也就是原始類型的“包裝對象”。

我們可以通過構造函數,將原始類型轉化為對應的對象即包裝對象,從而是原始類型能夠方便的調用某些方法

數值,字符串,布爾值的類型轉換函數分別是 Number,String,Boolean,在調用的時候在函數前面加上New 就變成了構造函數,能夠蔣對應的原始類型轉化為“包裝對象”

var v1 = new Number(123);
var v2 = new String("abc");
var v3 = new Boolean(true);

typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"

v1 === 123 // false
v2 === "abc" // false
v3 === true // false
類型轉換

類型轉換分為強制類型轉換和自動轉換,javascript 是動態類型語言,在到嗎解析運行時,需要的數據類型和傳入的數據類型不一致的時候,javascript 會進行自動類型轉化。當然,你也可以通過類型轉換方法進行強制類型裝換。

日常開發中,我們最常用的數據類型自動轉換不過就下面三種情況

不同數據類型之間相互運算

"2"+4 // "24"

對非布爾值進行布爾運算

if("22"){
  console.log("hello")
}

對非數據類型使用一元運算符

+"12"  //12

我們也通過 Number ,String,Boolean 來進行強制數據類型轉換。強制類型轉化的規則有點復雜,我們來了解一下。

Number 轉換 引用阮老師的詳細解釋

第一步,調用對象自身的valueOf方法。如果返回原始類型的值,則直接對該值使用Number函數,不再進行后續步驟。

第二步,如果 valueOf 方法返回的還是對象,則改為調用對象自身的 toString 方法。如果 toString 方法返回原始類型的值,則對該值使用 Number 函數,不再進行后續步驟。

第三步,如果 toString 方法返回的是對象,就報錯。

String 轉換方法同樣也是通過調用原對象的 toString 方法和 valueOf 方法,但是不同的是 String 函數會先調用 toString 方法進行轉換

Boolean 的轉換規則會相對簡單一些,除了幾個特殊的值,都會被轉化為 true

undefined
null
+0或-0
NaN
""(空字符串)

但是要注意

Boolean("false") //true
typeof
typeof 操作符返回數據類型,但是由于 javascript 設計的歷史原因,typeof 現已經不能滿足我們現在對于類型判斷的要求了
Value Class Type
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function functio
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
null null object

我們可以看到,typeof 不能區分對象的數組和日期,還會把 null 判斷成對象,那我們一般是什么時候用 typeof 呢。我們可以用來判斷一個已經定義的變量是否被賦值。

var a
if(typeof a == "undefined"){
  console.log("a 已經被定義")
}
instanceof
instanceof 操作符通常用來判斷,一個對象是否在另一個對象的原型鏈上,需要注意的是 instanceof 的左值是對象,右值是構造函數
// defining constructors
function C() {}
function D() {}

var o = new C();

// true, because: Object.getPrototypeOf(o) === C.prototype
o instanceof C;

// false, because D.prototype is nowhere in o"s prototype chain
o instanceof D;

#### Object.prototype.toString

那么我們有沒有可以用來區分變量數據類型的方法呢,有,Object.prototype.toString

一些原始數據類型也有 toString 方法,但是通常他們的 toString 方法都是改造過的,不能進行 數據類型判斷,所以我們需要用 Object 原型鏈上的 toString 方法

var a = 1234
a.toString() // "1234"

Object.prototype.toString.call(a) // "[object Number]"

不同類型返回的結果如下:

 1. 數值 [object Number]
 2. 字符串 [object String]
 3.布爾值 [object Boolean]
 4.undefined [object undefined]
 5.null  [object Null]
 6.數組 [object Array]
 7.arguments [object Arguments]
 8.函數 [object function]
 9.Error [object Error]
 10.Date [object Date]
 11.RegExp [object RegExp]
 12.其他對象 [object object]

那么我們就能夠通過 Object.prototype.toString 方法,封裝一個可以判斷變量數據類型的函數了

function type(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1);
}

type(function(){}) //"Function"
這次我們從對象、函數、類型三方面入手了解了javascript 中容易被忽視或則說比較難理解的地方,我會繼續將我在學習中積累的內容分享給大家,如果大家覺得文章有需要改進或則有其他想要了解的內容的,歡迎私信,評論或則微信我,646321933

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/93934.html

相關文章

  • JavaScript類型:關于類型,有哪些知道細節

    摘要:通過拆箱轉換,把對象編程基本類型,再從從基本類型轉換成對應的或者。拆箱轉換會嘗試調用和來獲得拆箱后的基本類型。 undefined和null ??Undefined類型表示未定義,它的類型只有一個值為undefined。任何變量在賦值前都是undefined類型,值為undefined。但是JS中undefined是一個變量,并非是一個關鍵字,為了避免無意中的篡改,使用void 0來獲...

    JessYanCoding 評論0 收藏0
  • 那些被忽略 JavaScript 數組方法細節

    摘要:這兩個方法的參數是一致的,回調函數和執行回調函數時使用的值,回調函數中的參數也是一致的,分別是數組當前元素當前元素索引和數組本身。 青湛(GitHub/mintsweet) 原文鏈接 前言 自以為還算一個比較高產的人吧~但是感覺好久都沒有寫點什么沒有營養的東西了,這一篇本來是打算去年年底都要拿出來說一說的,但是年底事情太多了,加上我真的變懶了拖到現在才要把這個準備了好久的標題完善一下...

    jsyzchen 評論0 收藏0
  • 精讀《知道javascript(中卷)》

    摘要:強制類型轉換本章介紹了的數據類型之間的轉換即強制類型轉換包括顯式和隱式。強制類型轉換常常為人詬病但實際上很多時候它們是非常有用的。隱式強制類型轉換則沒有那么明顯是其他操作的副作用。在處理強制類型轉換的時候要十分小心尤其是隱式強制類型轉換。 前言 《你不知道的 javascript》是一個前端學習必讀的系列,讓不求甚解的JavaScript開發者迎難而上,深入語言內部,弄清楚JavaSc...

    李世贊 評論0 收藏0
  • JavaScript工廠模式

    摘要:基于工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。工廠方法模式之所以又被稱為多態工廠模式,是因為所有的具體工廠類都具有同一抽象父類。工廠方法模式總結工廠方法模式是簡單工廠模式的進一步抽象和推廣。 JavaScript工廠模式 首先需要說一下工廠模式。工廠模式根據抽象程度的不同分為三種 簡單工廠模式 工廠方法模式 抽象工廠模式 1.簡單工廠模式 簡單工廠模式:又稱為靜態工廠方法...

    oujie 評論0 收藏0
  • 重學前端學習筆記(六)--JavaScript類型有哪些知道細節

    摘要:的碼點被稱為基本字符區域。關于的介紹,我準備用文檔阮一峰來做一些介紹,具體的可以參考文檔引入的原因的對象屬性名都是字符串,這容易造成屬性名的沖突。其他的一些屬性可以去看文檔阮一峰注意函數前不能使用命令,否則會報錯。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完...

    Lsnsh 評論0 收藏0

發表評論

0條評論

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