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

資訊專欄INFORMATION COLUMN

悄悄地說一個(gè)bug

layman / 2841人閱讀

摘要:客觀別急,今天真的是要說一個(gè),也許你早已知曉,也許你時(shí)常躺槍于他手,悄悄地,我們慢慢開始。使用案例源碼用到了前面已經(jīng)寫好的函數(shù),所以認(rèn)為獲取的屬性值,不包括原型返回一個(gè)副本,使其鍵和值對(duì)換。

前言

underscore.js源碼分析第四篇,前三篇地址分別是,如果你對(duì)這個(gè)系列感興趣,歡迎點(diǎn)擊watch,隨時(shí)關(guān)注動(dòng)態(tài)。

教你認(rèn)清這8大殺手锏

那些不起眼的小工具?

(void 0)與undefined之間的小九九

原文地址
源碼地址

逗我呢?哥!你要說什么bug,什么bug,什么bug,我最討厭bug。去他妹的bug。

客觀別急,今天真的是要說一個(gè)bug,也許你早已知曉,也許你時(shí)常躺槍于他手,悄悄地,我們慢慢開始。

for in 遍歷對(duì)象屬性時(shí)存在bug

for in 遍歷對(duì)象屬性時(shí)存在bug

for in 遍歷對(duì)象屬性時(shí)存在bug

使用for in去遍歷一個(gè)對(duì)象俺們?cè)偈煜げ贿^了,經(jīng)常干這種事,那他到底可以遍歷一個(gè)對(duì)象哪些類型的屬性呢? 長(zhǎng)得帥的還是看起來美美的,瞎說,它能夠遍歷的是對(duì)象身上那些可枚舉標(biāo)志([[Enumerable]])為true的屬性。

對(duì)于通過直接的賦值和屬性初始化的屬性,該標(biāo)識(shí)值默認(rèn)為即為 true

對(duì)于通過 Object.defineProperty 等定義的屬性,該標(biāo)識(shí)值默認(rèn)為 false

舉個(gè)例子哪些屬性可以被枚舉

let Person = function (name, sex) {
  this.name = name
  this.sex = sex
}

Person.prototype = {
  constructor: Person,
  showName () {
    console.log(this.name)
  },
  showSex () {
    console.log(this.sex)
  }
}

Person.wrap = {
  sayHi () {
    console.log("hi")
  }
}

var p1 = new Person("qianlongo", "sex")

p1.sayBye = () => {
  console.log("bye")
}

p1.toString = () => {
  console.log("string")
}

Object.defineProperty(p1, "info", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: "feDev"
});?

for (var key in p1) {
  console.log(key)
}


// name
// sex
// sayBye
// constructor
// showName
// showSex
// toString

可以看到我們手動(dòng)地用defineProperty,給某個(gè)對(duì)象設(shè)置屬性時(shí),enumerable為false此時(shí)該屬性是不可枚舉的

Person繼承自O(shè)bject構(gòu)造函數(shù),但是for in并沒有枚舉出Object原型上的一些方法

手動(dòng)地覆蓋對(duì)象原型上面的方法toString也是可枚舉的

如何判斷一個(gè)對(duì)象的屬性是可枚舉的

方式其實(shí)很簡(jiǎn)單,使用原生js提供的Object.propertyIsEnumerable來判斷

let obj = {
  name: "qianlongo"
}

let obj2 = {
  name: "qianlongo2",
  toString () {
    return this.name
  }
}

obj.propertyIsEnumerable("name") // true
obj.propertyIsEnumerable("toString") // false

obj2.propertyIsEnumerable("name") // true
obj2.propertyIsEnumerable("toString") // true

為什么obj判斷toString為不可枚舉屬性,而obj2就是可枚舉的了呢?原因很簡(jiǎn)單,obj2將toString重寫了,而一個(gè)對(duì)象自身直接賦值的屬性是可被枚舉的

說了這么多,接下來我們來看一下下劃線中涉及到遍歷的部分對(duì)象方法,come on!!!

_.has(object, key)

判斷對(duì)象obejct是否包含key屬性

平時(shí)你可能經(jīng)常這樣去判斷一個(gè)對(duì)象是否包含某個(gè)屬性

if (obj && obj.key) {
  // xxx
}

但是這樣做有缺陷,比如某個(gè)屬性其對(duì)應(yīng)的值為0,null,false,""空字符串呢?這樣明明obj有以下對(duì)應(yīng)的屬性,卻因?yàn)閷傩灾禐?strong>假而通過不了驗(yàn)證

let obj = {
  name: "",
  sex: 0,
  handsomeBoy: false,
  timer: null
}

所以我們可以采用下劃線中的這種方式

源碼

var hasOwnProperty = ObjProto.hasOwnProperty;
_.has = function(obj, key) {
  return obj != null && hasOwnProperty.call(obj, key);
};
_.keys(object)

獲取object對(duì)象所有的屬性名稱。

使用示例

let obj = {
  name: "qianlongo",
  sex: "boy"
}

let keys = _.keys(obj)
// ["name", "sex"]

源碼

_.keys = function(obj) {
  // 如果obj不是object類型直接返回空數(shù)組
  if (!_.isObject(obj)) return [];
  // 如果瀏覽器支持原生的keys方法,則使用原生的keys
  if (nativeKeys) return nativeKeys(obj);
  var keys = [];
  // 注意這里1、for in會(huì)遍歷原型上的鍵,所以用_.has來確保讀取的只是對(duì)象本身的屬性
  for (var key in obj) if (_.has(obj, key)) keys.push(key);
  // Ahem, IE < 9.
  // 這里主要處理ie9以下的瀏覽器的bug,會(huì)將對(duì)象上一些本該枚舉的屬性認(rèn)為不可枚舉,詳細(xì)可以看collectNonEnumProps分析
  if (hasEnumBug) collectNonEnumProps(obj, keys); 
  return keys;
};
collectNonEnumProps函數(shù)分析

該函數(shù)為下劃線中的內(nèi)部函數(shù)一枚,專門處理ie9以下的枚舉bug問題,for in到底有啥bug,終于可以說出來了。

簡(jiǎn)單地說就是如果對(duì)象將其原型上的類似toString的方法覆蓋了的話,那么我們認(rèn)為toString就是可枚舉的了,但是在ie9以下的瀏覽器中還是認(rèn)為是不可以枚舉的,又是萬惡的ie

源碼

// 判斷瀏覽器是否存在枚舉bug,如果有,在取反操作前會(huì)返回false
var hasEnumBug = !{toString: null}.propertyIsEnumerable("toString"); 
// 所有需要處理的可能存在枚舉問題的屬性
var nonEnumerableProps = ["valueOf", "isPrototypeOf", "toString",
                    "propertyIsEnumerable", "hasOwnProperty", "toLocaleString"]; 

// 處理ie9以下的一個(gè)枚舉bug                      
function collectNonEnumProps(obj, keys) {
  var nonEnumIdx = nonEnumerableProps.length;
  var constructor = obj.constructor;
  // 讀取obj的原型
  var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;  

  // 這里我有個(gè)疑問,對(duì)于constructor屬性為什么要多帶帶處理?
  // Constructor is a special case.
  var prop = "constructor"; 
  if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);

  while (nonEnumIdx--) {
    prop = nonEnumerableProps[nonEnumIdx];
    // nonEnumerableProps中的屬性出現(xiàn)在obj中,并且和原型中的同名方法不等,再者keys中不存在該屬性,就添加進(jìn)去
    if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
      keys.push(prop);
    }
  }
}

代碼看起來并不復(fù)雜,但是有一個(gè)小疑問,對(duì)于constructor屬性為什么要多帶帶處理呢?各個(gè)看官,如果知曉,請(qǐng)教我啊

_.allKeys(object)

獲取object中所有的屬性,包括原型上的。

舉個(gè)簡(jiǎn)單的例子說明

let Person = function (name, sex) {
  this.name = name
  this.sex = sex
}

Person.prototype = {
  constructor: Person,
  showName () {
    console.log(this.name)
  }
}

let p = new Person("qianlongo", "boy")

_.keys(p)
// ["name", "sex"] 只包括自身的屬性


_.allKeys(p)
// ["name", "sex", "constructor", "showName"] 還包括原型上的屬性

接下來看下源碼是怎么干的

源碼

// 獲取對(duì)象obj的所有的鍵
// 與keys不同,這里包括繼承來的key

// Retrieve all the property names of an object.
_.allKeys = function(obj) {
  if (!_.isObject(obj)) return [];
  var keys = [];
  // 直接讀遍歷取到的key,包括原型上的
  for (var key in obj) keys.push(key); 
  // Ahem, IE < 9.
  if (hasEnumBug) collectNonEnumProps(obj, keys); // 同樣處理一下有枚舉問題的瀏覽器
  return keys;
};

可以看到和_.keys的唯一的不同就在于遍歷obj的時(shí)候有沒有用hasOwnProperty去判斷

_.values()

返回object對(duì)象所有的屬性值。

使用案例

let obj = {
  name: "qianlongo",
  sex: "boy"
}

_.values(obj)
// ["qianlongo", "boy"]

源碼

// Retrieve the values of an object"s properties.
_.values = function(obj) {
  // 用到了前面已經(jīng)寫好的keys函數(shù),所以values認(rèn)為獲取的屬性值,不包括原型
  var keys = _.keys(obj);
  var length = keys.length;
  var values = Array(length);
  for (var i = 0; i < length; i++) {
    values[i] = obj[keys[i]];
  }
  return values;
};

_.invert(object)

返回一個(gè)object副本,使其鍵(keys)和值(values)對(duì)換。

使用案例

let obj = {
  name: "qianlongo",
  secName: "qianlongo",
  age: 100
}

_.invert(obj)

// {100: "age", qianlongo: "secName"}

注意喲,如果對(duì)象中有些屬性值是相等的,那么翻轉(zhuǎn)過來的對(duì)象其key取最后一個(gè)

源碼

_.invert = function(obj) {
  var result = {};
  // 所以也只是取對(duì)象本身的屬性
  var keys = _.keys(obj); 
  for (var i = 0, length = keys.length; i < length; i++) {
    // 值為key,key為值,如果有值相等,后面的覆蓋前面的
    result[obj[keys[i]]] = keys[i]; 
  }
  return result;
};
_.functions(object)

返回一個(gè)對(duì)象里所有的方法名, 而且是已經(jīng)排序的(注意這里包括原型上的屬性)

源碼

_.functions = _.methods = function(obj) {
  var names = [];
  for (var key in obj) {
    // 是函數(shù),就裝載進(jìn)去
    if (_.isFunction(obj[key])) names.push(key);
  }
  return names.sort(); // 最后返回經(jīng)過排序的數(shù)組
};
結(jié)尾

夜深人靜,悄悄地說一個(gè)bug這個(gè)鬼故事講完了,各位good night。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/82939.html

相關(guān)文章

  • 我在全球最大的同性社交平臺(tái)那點(diǎn)事

    摘要:從最大的同性社交平臺(tái)獲取數(shù)據(jù)好了,言歸正傳,回到題目。烏云密布的爬蟲百度網(wǎng)盤這件事,是我不想看到的,這類安全問題的一個(gè)共同特點(diǎn)用戶自身確實(shí)存在問題。 本文作者:夏之冰雪,i春秋簽約作家 《我在百度網(wǎng)盤上看到上萬條車主個(gè)人信息,企業(yè)、政府高官信息、各種數(shù)據(jù)庫和無窮無盡的盜版》,一時(shí)間,這篇文章就火了,火爆程度另百度猝不及防。 其實(shí)呢,這事真不能全怪百度,畢竟用戶分享出去了。之所以引起這么...

    AlphaWatch 評(píng)論0 收藏0
  • 蜷縮在你耳膜邊的AI

    摘要:蘋果公司也參與進(jìn)來蘋果將在新版上取消耳機(jī)插孔,取而代之的可能是一對(duì)無線。蘋果在上線之前就建立了全世界第一個(gè)數(shù)據(jù)中心,耗資億美元,用來進(jìn)行的計(jì)算。它是一個(gè)蜷縮在你的耳膜附近的或者。外加你還得忍受耳廓的疼痛。整體滿意度將只能徘徊在或。 多希望我可以觸碰你。 西奧多躺在床上,靜靜地說。他的生活中充滿了沉默與拒絕,但這一次,塞曼莎溫柔地問:你想怎樣觸碰我呢? showImg(https://s...

    zhichangterry 評(píng)論0 收藏0
  • 深度學(xué)習(xí)的這些坑你都遇到過嗎?神經(jīng)網(wǎng)絡(luò)11大常見陷阱及應(yīng)對(duì)方法

    摘要:類似地,輸入中的大規(guī)模特征將主導(dǎo)網(wǎng)絡(luò)并導(dǎo)致下游發(fā)生更大的變化。因此,使用神經(jīng)網(wǎng)絡(luò)庫的自動(dòng)規(guī)范化往往是不夠的,這些神經(jīng)網(wǎng)絡(luò)庫會(huì)在每個(gè)特征的基礎(chǔ)上盲目地減去平均值并除以方差。 如果你的神經(jīng)網(wǎng)絡(luò)不工作,該怎么辦?作者在這里列出了建神經(jīng)網(wǎng)絡(luò)時(shí)所有可能做錯(cuò)的事情,以及他自己的解決經(jīng)驗(yàn)。忘記規(guī)范化數(shù)據(jù)忘記檢查結(jié)果忘記預(yù)處理數(shù)據(jù)忘記使用正則化使用的batch太大使用了不正確的學(xué)習(xí)率在最后層使用了錯(cuò)誤的激活...

    DirtyMind 評(píng)論0 收藏0
  • 2017前端發(fā)展回顧

    摘要:前端開發(fā)在年依然持續(xù)火熱,本文將對(duì)熱點(diǎn)事件做一個(gè)總結(jié)。版的和協(xié)議在前端領(lǐng)域,一直獨(dú)占鰲頭。年又發(fā)布了一個(gè)重大的版本更新。主要是配合使用了服務(wù)工作線程。而且還提供了供前端開發(fā)者接入。快速發(fā)布了和在悄悄地跳過之后,在月號(hào)正式發(fā)布。 譯者按: 老技術(shù)日趨成熟,新技術(shù)層出不窮。 原文: A recap of front-end development in 2017 譯者: Fundebu...

    lmxdawn 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<