摘要:本文為知識整理,可能工作中用到這些東西不多,可是總有人想讓你會前言小時候很渴望長大,羨慕大人們的財富自由長大后又很羨慕小時候,懷念小時候的無憂無慮,守候著那份天真。哦,還有,不是長大就能財富自由。。。
本文為知識整理,可能工作中用到這些東西不多,可是總有人想讓你會
前言:小時候很渴望長大,羨慕大人們的財富自由;長大后又很羨慕小時候,懷念小時候的無憂無慮,守候著那份天真。哦,還有,不是長大就能財富自由。。。
一:js繼承①:對象冒充實現(xiàn)繼承:(可實現(xiàn)多繼承)
——原理:讓父類構(gòu)造函數(shù)成為子類的方法,然后調(diào)用子類的方法,通過this關(guān)鍵字給所有屬性和方法賦值
function Parent(name) { this.name=name; this.sayName=function () { console.log(this.name); } } function Child (cname) { this.parent=Parent; this.parent(cname); delete this.parent; // 刪除無用的parent函數(shù) == f Parent(name) } var mychild=new Child("名字"); mychild.sayName();
②:原型鏈繼承 (不能實現(xiàn)多繼承)
prototype
function Parent (name, age) { this.name = name; this.age = age; this.ParFunc = function () { console.log(this.height) } }; Parent.prototype.sayName = function () { console.log(this) }; function Child (cname, cage, height) { this.height = height } Child.prototype = new Parent(); // Child原型指向Parent的一個實例 Child.prototype.constructor = Child; // 把Child指向自己,不與Parent共享 var child = new Child("測試名字", "測試年齡", "測試身高") console.log(child) // 發(fā)現(xiàn)打印出來的屬性都繼承了,就是沒值
child.ParFunc():當訪問ParFunc屬性時,會先在child的實例屬性中尋找,找不到就去child的原型對象上去找。一層一層的尋找構(gòu)成了原型鏈
因為無法向父類構(gòu)造函數(shù)傳參;可以 new Parent("名字", "年齡")這時傳參
注:如果想用原型給Child拓展方法:
Child.prototype.childHeight = function () { console.log(this.height) }
一定要寫到Child.prototype = new Parent()的下面,要么就被覆蓋掉了。
③:call、apply繼承(不能繼承原型鏈,prototype上的)
function Parent (name, age) { this.name = name; this.age = age; this.ParFunc = function () { console.log(this.name) } } function Child (cname, cage, height) { Parent.call(this,cname,cage); // 繼承的參數(shù)為當前函數(shù)的形參 // apply: Parent.call(this,arguments); this.height = height; } var child = new Child("測試名字", "測試年齡", "測試身高") console.log(child) // ParFunc: ? () age: "測試年齡" name: "測試名字"
④:組合繼承:call+原型鏈繼承
function Parent (name, age) { this.name = name; this.age = age; this.ParFunc = function () { console.log(this.height) } } Parent.prototype.sayName = function () { console.log(this) } function Child (cname, cage, height) { Parent.call(this, cname, cage); // 解決傳參問題 this.height = height; }; Child.prototype = new Parent() Child.prototype.constructor = Child; // 把Child指向自己,否則一直指向Parent var child = new Child("測試名字", "測試年齡", "測試身高")
比較常用的繼承方式,缺點是 兩次調(diào)用 Parent構(gòu)造函數(shù)
⑤:寄生組合繼承:
cal+prototype
function Parent (name, age) { // 父函數(shù) this.name = name; this.age = age; this.ParFunc = function () { console.log(this.height) } } Parent.prototype.sayName = function () { console.log(this) } function Child (cname, cage, height) { // 子函數(shù) Parent.call(this, cname, cage) this.height = height; }; var createObj = function () { // 中間函數(shù)繼承 Parent function Trans() {}; Trans.prototype = Parent.prototype; return new Trans(); }; Child.prototype = createObj() Child.prototype.constructor = Child; // 改回指針 var child = new Child("名字", "年齡", "身高") console.log(child)二:如何獲取自定義屬性,特例data-*如何獲取
官方定義:
data-*是 **html5** 新屬性 主要用于存儲頁面的自定義數(shù)據(jù) 不應(yīng)該包含大寫字母(會默認轉(zhuǎn)為小寫) 注釋:用戶代理會完全忽略前綴為 "data-" 的自定義屬性。
腦海里第一印象就是 getAttribute(),setAttribute()倆屬性了,一個獲取,一個設(shè)置
而平時又很少用到,但是平時用的框架什么的多數(shù)都用 data-* 這個自定義屬性,那其實獲取 data- 這類自定義屬性的時候,還有個更方便的方法dataset
eg:var div1 = document.getElementById("div1") console.log(div1.dataset) // DOMStringMap {a: "測試", b: "222"}a: "測試"b: "222"
用data-*作為自定義屬性:可以一句話就獲取到所有屬性,獲取方式也簡便
三:事件的幾個階段:捕獲、目標(event.target,即觸發(fā)過程)、冒泡先盜個圖
——冒泡(IE事件流):從最深的節(jié)點向外傳播,div -> window,就好比往水里丟一個石子,一層層波浪抵達河邊緣
——捕獲(網(wǎng)景):從最外層向目標傳遞,window -> div,就好比你去一個大企業(yè)集團找人,需要提供公司 > 大部門 > 小部門 > 小組 > 目標
——目標:即觸發(fā)過程event.target
——target、currentTarget的區(qū)別:target這個屬性指向的是目標過程中的DOM對象,也就是 觸發(fā)事件監(jiān)聽的對象, currentTarget這個指向的是當前的對象,具體內(nèi)容跟this一樣,當this指向的是目標的時候(事件的目標階段),target與currentTarget相同
——現(xiàn)在幾乎所有的主流瀏覽器都支持冒泡;IE早起版本會跳過html直接跳到document,且不支持捕獲。
——平時多數(shù)用到冒泡多一些,事件代理(委托)也是通過事件冒泡的原理,讓DOM節(jié)點可追溯,也可以利用冒泡的原理做埋點,避免新增DOM節(jié)點,改代碼上線
——事件句柄addEventListener("事件名", "function", false),默認冒泡
四:判斷數(shù)據(jù)類型,返回數(shù)據(jù)的具體類型emm... 那不就直接 return typeof n 不就完了,哦不對,再識別一下數(shù)組,因為數(shù)組的typeof也是對象,Array.isArray(n)...
/^12/ 這返回啥? wc,也是object吧,那咋區(qū)分,對,正則有test方法,再判斷一下
if (n.test) { return "RegExp" }
null好像也返回obj吧,時間 Date嘞,都返回obj也沒毛病,萬物皆對象啊。
據(jù)說instanceof也可以:左側(cè)是否是右側(cè)的實例,也就是說每個類型我們都得判斷,于是
[] instanceof Array // true [] instanceof Object // true
不光麻煩,返回的也不精確啊
據(jù)說constructor也可以:js引擎會為函數(shù)添加prototype,并讓其指向"該函數(shù)"的引用
/^12/.constructor // f RexExp(){[native code]}
new Date().constructor // ? Date() { [native code] }
null.constructor // 報錯:Cannot read..
undefined.constructor // 報錯:Cannot read..
發(fā)現(xiàn)確實能校驗一些typeof 不能校驗的,但是 null和undefined沒有"指針"啊,而且寫繼承的時候,指針是可以被改的,稍不注意就涼涼了...
把這些都整合到一起基本也都夠用了,可是并不優(yōu)雅
有請toString登場....
華麗分割線
toString() 是 Object 的原型方法,調(diào)用該方法,默認返回當前對象的 [[Class]] 。這是一個內(nèi)部屬性,其格式為 [object Xxx] ,其中 Xxx 就是對象的類型。完美~~
Object.prototype.toString.call(null) ; // [object Null] Object.prototype.toString.call(new Function()) ; // [object Function] Object.prototype.toString.call(new Date()) ; // [object Date]
但是我覺得除了obj比較特殊之外,其他類型,typeof都可以判斷,不需要再多調(diào)用一次toString方法,所以最終封裝 =>
function typeDetection (n) { if (typeof n === "object") { return Object.prototype.toString.call(n) } else { return typeof n } }
直接調(diào)用typeDetection("") // string
五:千分位的實現(xiàn)Q:字符:1234567890.12 轉(zhuǎn)換為:1,234,567,890.12
R:
個人用了while循環(huán)的方式
function strFilter (str) { let newStr = String(str).split(".") // 切分原始字符,兼容傳入Number類型 let transStr = newStr[0],resStr = [] while (transStr/1000 > 1) { // 判斷是否大于1000 let whildStr = String((transStr/1000).toFixed(3)).split(".") // 這里一定要保留三位小數(shù),否則正數(shù)部分末位的0就會丟失,又轉(zhuǎn)為String,因為Number沒有split方法 transStr = whildStr[0] // 每次都取小數(shù)點以前的(正數(shù)部分) resStr.unshift(whildStr[1]) // 向前插入小數(shù)點后的數(shù)字() } // 除以1000剩下的數(shù) + 每次除以1000后的數(shù) + 原來小數(shù) let res2 = newStr[1]?("." + newStr[1]):"" let resComma = resStr.length?("," + resStr.join(",")): "" return transStr + resComma + res2 }
雖然實現(xiàn)代碼很多,但個人覺得還算易懂
網(wǎng)上看到用正則的,確實簡短:
function strFilter2 (n) { let s = String(n) let re = /d{1,3}(?=(d{3})+$)/g let n1 = s.replace(/^(d+)((.d+)?)$/, function (s, s1, s2) { return s1.replace(re, "$&,") + s2 }) return n1 }
其實正則在好多場景都體現(xiàn)出優(yōu)勢,只是不能被輕易想到
Q:以下this指向
(function () { "use strict"; console.log(this) // undefined })() (function () { "use strict"; console.log(this) // window })()
R:嚴格模式下,除構(gòu)造函數(shù)、對象內(nèi)置函數(shù)外,this均指向 undefined
Q:script標簽的 async、defer啥區(qū)別?
R:別說那沒用的,上圖
啥也不加:script讀取和解析腳本階段都會阻斷頁面執(zhí)行,
加async : script解析腳本階段會阻斷頁面執(zhí)行
加defer : scriptj腳本將在頁面完成解析時執(zhí)行
Q:[1,2,3].map(parseInt)的結(jié)果?
R:之前用到parseInt,只知道是向下取整,翻了下w3c的parseInt定義: Crazy
再看map,
parseInt就是回調(diào)函數(shù),map會傳給parseInt三個參數(shù),parseInt只識別前兩個,
那也就是得到了
function parseInt1 (item, index) { return parseInt(item,index) }
得到 parseInt(1,0) parseInt(2,1) parseInt(3,2)
parseInt(1,0),parseInt定義radix不傳或者0,按10進制,也就得到了1 parseInt(2,1),parseInt又定義第二個參數(shù) radix 位于 2-36(除了0),否則返回NaN,所以得到NaN parseInt(3,2),這個據(jù)說(網(wǎng)上)是 3不是 2的合法進制數(shù) (只有0和1),但是個人試了試 parseInt(10,2) => 3,parseInt(20, 2) => 6,parseInt(30, 2) => NaN ,發(fā)現(xiàn)只要是字符首字符小于 radix都是可以的,但是一旦首字符 >= radix,就會返回NaN
參考文章:判斷js數(shù)據(jù)類型的四種方法
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/53839.html
摘要:本文為知識整理,可能工作中用到這些東西不多,可是總有人想讓你會前言小時候很渴望長大,羨慕大人們的財富自由長大后又很羨慕小時候,懷念小時候的無憂無慮,守候著那份天真。哦,還有,不是長大就能財富自由。。。 本文為知識整理,可能工作中用到這些東西不多,可是總有人想讓你會 前言:小時候很渴望長大,羨慕大人們的財富自由;長大后又很羨慕小時候,懷念小時候的無憂無慮,守候著那份天真。哦,還有,不是...
摘要:本文為知識整理,可能工作中用到這些東西不多,可是總有人想讓你會前言小時候很渴望長大,羨慕大人們的財富自由長大后又很羨慕小時候,懷念小時候的無憂無慮,守候著那份天真。哦,還有,不是長大就能財富自由。。。 本文為知識整理,可能工作中用到這些東西不多,可是總有人想讓你會 前言:小時候很渴望長大,羨慕大人們的財富自由;長大后又很羨慕小時候,懷念小時候的無憂無慮,守候著那份天真。哦,還有,不是...
閱讀 2102·2021-11-19 09:58
閱讀 1701·2021-11-15 11:36
閱讀 2867·2019-08-30 15:54
閱讀 3386·2019-08-29 15:07
閱讀 2759·2019-08-26 11:47
閱讀 2805·2019-08-26 10:11
閱讀 2496·2019-08-23 18:22
閱讀 2744·2019-08-23 17:58