中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

怎么對javascript的類型進行轉換

發布時間:2021-02-25 15:22:05 來源:億速云 閱讀:157 作者:戴恩恩 欄目:web開發

本文章向大家介紹怎么對javascript的類型進行轉換的基本知識點總結和需要注意事項,具有一定的參考價值,需要的朋友可以參考一下。

JavaScript可以做什么

1.可以使網頁具有交互性,例如響應用戶點擊,給用戶提供更好的體驗。 2.可以處理表單,檢驗用戶的輸入,并提供及時反饋節省用戶時間。 3.可以根據用戶的操作,動態的創建頁面。 4使用JavaScript可以通過設置cookie存儲在瀏覽器上的一些臨時信息。

實現一個函數,運算結果可以滿足如下預期結果:

add(1)(2) // 3
add(1, 2, 3)(10) // 16
add(1)(2)(3)(4)(5) // 15

對于一個好奇的切圖仔來說,忍不住動手嘗試了一下,看到題目首先想到的是會用到高階函數以及 Array.prototype.reduce()

高階函數(Higher-order function):高階函數的意思是它接收另一個函數作為參數。在 javascript 中,函數是一等公民,允許函數作為參數或者返回值傳遞。

得到了下面這個解法:

function add() {
 var args = Array.prototype.slice.call(arguments);
  return function() {
  var arg2 = Array.prototype.slice.call(arguments);
  return args.concat(arg2).reduce(function(a, b){
   return a + b;
  });
 }
}

驗證了一下,發現錯了:

add(1)(2) // 3
add(1, 2)(3) // 6
add(1)(2)(3) // Uncaught TypeError: add(...)(...) is not a function(…)

上面的解法,只有在 add()() 情形下是正確的。而當鏈式操作的參數多于兩個或者少于兩個的時候,無法返回結果。

而這個也是這題的一個難點所在,add()的時候,如何既返回一個值又返回一個函數以供后續繼續調用?

后來經過高人指點,通過重寫函數的 valueOf 方法或者 toString 方法,可以得到其中一種解法:

function add () {
 var args = Array.prototype.slice.call(arguments);
 var fn = function () {
  var arg_fn = Array.prototype.slice.call(arguments);
  return add.apply(null, args.concat(arg_fn));
 }
 fn.valueOf = function () {
  return args.reduce(function(a, b) {
   return a + b;
  })
 }
 return fn;
}

嗯?第一眼看到這個解法的時候,我是懵逼的。因為我感覺 fn.valueOf() 從頭到尾都沒有被調用過,但是驗證了下結果:

add(1) // 1
add(1,2)(3) //6
add(1)(2)(3)(4)(5) // 15

神奇的對了!那么玄機必然是在上面的 fn.valueOf = function() {} 內了。為何會是這樣呢?這個方法是在函數的什么時刻執行的?且聽我一步一步道來。

valueOf 和 toString

先來簡單了解下這兩個方法:

Object.prototype.valueOf()

用 MDN 的話來說,valueOf() 方法返回指定對象的原始值。

JavaScript 調用 valueOf() 方法用來把對象轉換成原始類型的值(數值、字符串和布爾值)。但是我們很少需要自己調用此函數,valueOf 方法一般都會被 JavaScript 自動調用。

記住上面這句話,下面我們會細說所謂的自動調用是什么意思。

Object.prototype.toString()

toString() 方法返回一個表示該對象的字符串。

每個對象都有一個 toString() 方法,當對象被表示為文本值時或者當以期望字符串的方式引用對象時,該方法被自動調用。

這里先記住,valueOf() 和 toString() 在特定的場合下會自行調用。

原始類型

好,鋪墊一下,先了解下 javascript 的幾種原始類型,除去 Object 和 Symbol,有如下幾種原始類型:

  • Number

  • String

  • Boolean

  • Undefined

  • Null

在 JavaScript 進行對比或者各種運算的時候會把對象轉換成這些類型,從而進行后續的操作,下面逐一說明:

String 類型轉換

在某個操作或者運算需要字符串的時候,會觸發 Object 的 String 轉換,舉個例子:

var obj = {name: 'Coco'};
var str = '123' + obj;
console.log(str); // 123[object Object]

轉換規則:

  • 如果 toString 方法存在并且返回原始類型,返回 toString 的結果。

  • 如果 toString 方法不存在或者返回的不是“原始類型”,調用valueOf 方法,如果 valueOf 方法存在,并且返回“原始類型”數據,返回 valueOf 的結果。

  • 其他情況,拋出錯誤。

上面的例子實際上是:

var obj = {name: 'Coco'};
var str = '123' + obj.toString();

其中,obj.toString() 的值為 "[object Object]"

假設是數組:

var arr = [1, 2];
var str = '123' + arr;
console.log(str); // 1231,2

上面 + arr 其實是調用了 + arr.toString()

但是,我們可以自己改寫對象的 toString,valueOf 方法:

var obj = {
  toString: function() {
    console.log('調用了 obj.toString');
    return '111';
  }
}
alert(obj);
// 調用了 obj.toString
// 111

上面 alert(obj) ,obj 會自動調用自己的 obj.toString() 方法轉化為原始類型,如果我們不重寫它的 toString 方法,將輸出 [object Object] ,這里我們重寫了 toString ,而且返回了一個原始類型字符串 111 ,所以最終 alert 出了 111。

上面的轉化規則寫了,toString 方法需要存在并且返回原始類型,那么如果返回的不是一個原始類型,則會去繼續尋找對象的 valueOf 方法:

下面我們嘗試證明如果 toString() 方法不可用的時候系統會調用 valueOf() 方法,下面我們改寫對象的 valueOf

var obj = {
  toString: function() {
    console.log('調用了 obj.toString');
    return {};
  },
  valueOf: function() {
    console.log('調用了 obj.valueOf')
    return '110';
  }
}
alert(obj);
// 調用了 obj.toString
// 調用了 obj.valueOf
// 110

從結果可以看到,當 toString 不可用的時候,系統會再嘗試 valueOf 方法,如果 valueOf 方法存在,并且返回原始類型(String、Number、Boolean)數據,返回valueOf的結果。

那么如果,toString 和 valueOf 返回的都不是原始類型呢?看下面這個例子:

var obj = {
  toString: function() {
    console.log('調用了 obj.toString');
    return {};
  },
  valueOf: function() {
    console.log('調用了 obj.valueOf')
    return {};
  }
}
alert(obj);
// 調用了 obj.toString
// 調用了 obj.valueOf
// Uncaught TypeError: Cannot convert object to primitive value

可以發現,如果 toString valueOf 方法均不可用的情況下,系統會直接返回一個錯誤。

Number 類型轉換

上面描述的是 String 類型的轉換,很多時候也會發生 Number 類型的轉換:

  • 調用 Number() 函數,強制進行 Number 類型轉換

  • 調用 Math.sqrt() 這類參數需要 Number 類型的方法

  • obj == 1 ,進行對比的時候

  • obj + 1 , 進行運算的時候

與 String 類型轉換相似,但是 Number 類型剛好反過來,先查詢自身的 valueOf 方法,再查詢自己 toString 方法:

  1. 如果 valueOf 存在,且返回原始類型數據,返回 valueOf 的結果。

  2. 如果 toString 存在,且返回原始類型數據,返回 toString 的結果。

  3. 其他情況,拋出錯誤。

按照上述步驟,分別嘗試一下:

var obj = {
  valueOf: function() {
    console.log('調用 valueOf');
    return 5;
  }
}
console.log(obj + 1);
// 調用 valueOf
// 6
var obj = {
  valueOf: function() {
    console.log('調用 valueOf');
    return {};
  },
  toString: function() {
    console.log('調用 toString');
    return 10;
  }
}
console.log(obj + 1);
// 調用 valueOf
// 調用 toString
// 11
var obj = {
  valueOf: function() {
    console.log('調用 valueOf');
    return {};
  },
  toString: function() {
    console.log('調用 toString');
    return {};
  }
}
console.log(obj + 1);
// 調用 valueOf
// 調用 toString
// Uncaught TypeError: Cannot convert object to primitive value

Boolean 轉換

什么時候會進行布爾轉換呢:

  • 布爾比較時

  • if(obj) , while(obj) 等判斷時

簡單來說,除了下述 6 個值轉換結果為 false,其他全部為 true:

  • undefined

  • null

  • -0

  • 0或+0

  • NaN

  • ''(空字符串)

Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false 

Function 轉換

好,最后回到我們一開始的題目,來講講函數的轉換。

我們定義一個函數如下:

function test() {
  var a = 1;
  console.log(1);
}

如果我們僅僅是調用 test 而不是 test() ,看看會發生什么?

可以看到,這里把我們定義的 test 函數的重新打印了一遍,其實,這里自行調用了函數的 valueOf 方法:

我們改寫一下 test 函數的 valueOf 方法。

test.valueOf = function() {
  console.log('調用 valueOf 方法');
  return 2;
} 
test;
// 輸出如下:
// 調用 valueOf 方法
// 2

與 Number 轉換類似,如果函數的 valueOf 方法返回的不是一個原始類型,會繼續找到它的 toString 方法:

test.valueOf = function() {
  console.log('調用 valueOf 方法');
  return {};
}
test.toString= function() {
  console.log('調用 toString 方法');
  return 3;
}
test;
// 輸出如下:
// 調用 valueOf 方法
// 調用 toString 方法
// 3

破題

再看回我正文開頭那題的答案,正是運用了函數會自行調用 valueOf 方法這個技巧,并改寫了該方法。我們稍作改變,變形如下:

function add () {
  console.log('進入add');
  var args = Array.prototype.slice.call(arguments);
  var fn = function () {
    var arg_fn = Array.prototype.slice.call(arguments);
    console.log('調用fn');
    return add.apply(null, args.concat(arg_fn));
  }
  fn.valueOf = function () {
    console.log('調用valueOf');
    return args.reduce(function(a, b) {
      return a + b;
    })
  }
  return fn;
}

當調用一次 add 的時候,實際是是返回 fn 這個 function,實際是也就是返回 fn.valueOf();

add(1);
// 輸出如下:
// 進入add
// 調用valueOf
// 1

其實也就是相當于:

[1].reduce(function(a, b) {
  return a + b;
})
// 1

當鏈式調用兩次的時候:

add(1)(2);
// 輸出如下:
// 進入add
// 調用fn
// 進入add
// 調用valueOf
// 3

當鏈式調用三次的時候:

add(1)(2)(3);
// 輸出如下:
// 進入add
// 調用fn
// 進入add
// 調用fn
// 進入add
// 調用valueOf
// 6

可以看到,這里其實有一種循環。只有最后一次調用才真正調用到 valueOf,而之前的操作都是合并參數,遞歸調用本身,由于最后一次調用返回的是一個 fn 函數,所以最終調用了函數的 fn.valueOf,并且利用了 reduce 方法對所有參數求和。

除了改寫 valueOf 方法,也可以改寫 toString 方法,所以,如果你喜歡,下面這樣也可以:

function add () {
  var args = Array.prototype.slice.call(arguments);
  var fn = function () {
    var arg_fn = Array.prototype.slice.call(arguments);
    return add.apply(null, args.concat(arg_fn));
  }
  fn.toString = function() {
    return args.reduce(function(a, b) {
      return a + b;
    })
  }
  return fn;
}

這里有個規律,如果只改寫 valueOf() 或是 toString() 其中一個,會優先調用被改寫了的方法,而如果兩個同時改寫,則會像 String 轉換規則一樣,優先查詢 valueOf() 方法,在 valueOf() 方法返回的是非原始類型的情況下再查詢 toString() 方法。

以上就是小編為大家帶來的怎么對javascript的類型進行轉換的全部內容了,希望大家多多支持億速云!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长治县| 无棣县| 福鼎市| 屯留县| 扎赉特旗| 大洼县| 浑源县| 红原县| 崇文区| 平昌县| 杭锦旗| 泸溪县| 乌兰浩特市| 米易县| 武川县| 兴山县| 普兰县| 区。| 大兴区| 辽阳市| 崇义县| 紫阳县| 和硕县| 肃南| 商南县| 巴楚县| 天水市| 阜新| 安多县| 湖北省| 昌图县| 应用必备| 吉隆县| 宜丰县| 昌吉市| 会理县| 桦甸市| 桑植县| 肥乡县| 昌邑市| 正蓝旗|