ES5-20 复习
3-1
- 變量單一聲明方式
- String Boolean undefined Number null
- undefined == null
- typeof(null) ‘object’
- typeof(方法) ‘function’
- typeof(+) +是運算符,不是數據類型 報錯
- +0 === -0 true
- +Infinity == -Infinity false
- NaN和誰都不等
- 原始值沒有屬性 要打印屬性、調用方法得經過基本包裝類
- 包裝了還沒有就沒辦法了,比如length屬性
- Boolean、Number包裝了也沒有length,打印就是undefined
- 可以給包裝類添加值以外的屬性
- 數字直接跟.有歧義,會認為是小數點
- 三種基本包裝類的toString、valueOf方法各不相干+
- Function的toString、valueOf都返回函數體?
- Object的toString
- Array的toString,返回用逗號隔開
- 要打印反斜杠,單雙引號必須使用字符字面量,否則報錯
- 并且字符字面量還要用引號引起來
- Object Array Function Date RegExp
- 對象的屬性是字符串類型
一些現象
3-2
- 目前證實會終止程序的有:語法錯誤、范圍錯誤
- 0/0 NaN
- 1/0 +Infinity
- 逗號運算符在表達式中只返回最后一個
- ASCII碼 0-255
3-3
- 顯示類型轉換,Number對null、true、false,數組友好轉010
- Number對空數組和只有一個元素的數組友好
- Number對undefined、1a不友好轉NaN
- ParseInt只對數字開頭的友好
- null、undefined既不大于也不小于更不等于0(隱式類型轉換有坑)
3-4
- 函數聲明一定要有函數名,不然報錯
- 函數聲明不能直接調用(無參),會報語法錯誤
- 函數聲明function a(){}(1),這樣不報錯,會認為(1)是表達式不是調用
- 函數表達式可以()調用,是立即執行了
- 函數表達式,function后的函數名在外部不可見,但是.name總能獲得函數名(優先取function后的,沒有就取表達式聲明的變量名)
- es5&&實參非undefined時形參、實參互相統一
- es6、嚴格模式,形參、實參不統一
- 函數是對象
3-5
- 預編譯:函數聲明、函數整體提升
- 變量聲明,只有聲明提升,賦值不提升,所以AO一開始是undefined
- -1 + NaN + ‘’ 先做-1 + NaN得到NaN 再 +’’ 得到’NaN’
3-6
- 看作用域鏈,函數AO、GO的this指向的是window
- AO含this、arguments和變量聲明、函數聲明
- 閉包是指有權訪問另一個函數作用域中的變量的函數
- 立即執行函數內將閉包添加到全局,無法銷毀閉包對AO的引用
- 閉包不是將被拉扯的AO放到全局!
3-7
- 表達式會忽略函數名
- 注意,此時GO里也沒有b了
- 解決閉包總是拿到AO在循環中最后的值,用IIFE并實時傳值進去
3-8
- 對象中的this指向對象本身
- 構造函數,用new實例化后,函數內this指向實例
- 不用new實例化,this指向window
- 當構造函數return引用值時(除了this的函數、函數聲明、對象、數組、Date…),返回引用值,若是原始值則忽略
- 實例方法中的this,誰調用就指向誰
3-10
- 字面量方式改變構造函數prototype(指向新的對象)若在實例化前,則實例的__proto__會指向修改后的原型,若在實例化后,實例的__proto__還是指向默認的prototype
- 若使用xx.prototype.屬性 = 的修改方式(沒有指向新對象),則實例訪問到的屬性也會跟著蓋面
4-1
- 對于++ --,會計算再賦值,能讓實例增添屬性
- 將null作為實例的原型,實例中將不包含任何屬性!,將{}作為原型仍有__proto__
- 因此,不是所有對象都繼承Object.prototype
- 手動增加的__proto__和自身的不一樣,不能在手動增加的_proto__向上查找原型鏈
- 原型鏈的終點是Object.prototype
4-2
- 要在構造函數(而不是原型)中定義引用類型的屬性(防止所有實例共享引用值)
- 原型鏈實現繼承(子類的原型指向父類的實例)的問題一:子類的實例可能會共享引用類型值(原本是父類構造函數中定義的屬性)
- 問題二:不能傳參
- 借用構造函數(子類構造函數內:父類構造函數call(this)),解決了原型鏈繼承的問題,但函數無法復用,超類型原型中的方法,對子類型不可見
- 組合繼承(原型鏈+借用構造函數),問題:超類的構造函數都執行了2次
- Object.create(對象,{屬性:屬性描述符}),第二個參數將屬性添加到新對象上
- 寄生組合式繼承,用Object.create()指定新對象的__proto__,用**.constructor增強對象,結合call**
- 圣杯模式實現繼承:繼承父類原型上的屬性和方法,沒有解決引用類型值問題,構造函數不能傳值
4-3
- 對象遍歷(for (var key in obj))原型上的屬性也會打印,用hasOwnProperty區分(嚴謹)
- 數組遍歷(for (ele val of arr))// ele是每一項arr的值
- arguments.callee - 正在被執行的函數對象(在自啟動函數中使用遞歸,且不需要函數名)
- test.caller - test函數的調用者
for…of語句在可迭代對象(包括 Array,Map,Set,String,TypedArray,arguments 對象等等)上創建一個迭代循環,調用自定義迭代鉤子,并為每個不同屬性的值執行語句,可以由break, throw continue 或return終止。在這些情況下,迭代器關閉。
for…in不應該用于迭代一個關注索引順序的 Array。
Object.keys() 方法會返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和正常循環遍歷該對象時返回的順序一致 。
在ES5里,如果此方法的參數不是對象(而是一個原始值),那么它會拋出 TypeError。在ES2015中,非對象的參數將被強制轉換為一個對象。
4-4
- 手寫深拷貝,考慮原始值和引用值(區分數組和對象),結合遞歸
4-5
- new Array()的參數用于設置數組長度,或設置數組(只傳一個非數字值時)
- 數組方法 - 繼承了數組原型上的方法
- push、unshift(返回值:執行了方法以后數組長度,可以傳多個參數)
- pop、shift(返回剪切掉的那個值)
- splice(在哪個下標前添加,返回值空數組)
- 數組中認為最后一個元素的index是-1
- sort是按照ASCII碼排列的(未傳參時)
- sort(function(a,b){return 負數})
4-6
- concat 返回值是拼接后的數組
- slice[a,b)
- join不傳參數相當于toString!用逗號連接
- split(a,b) 不傳值,會將整個字符串放進數組;第二個參數b,是用a分割后截取b位
- 類數組沒有數組方法,因為沒有繼承Array.prototype,繼承Object.prototype,類數組
- 對象轉類數組:給對象加splice屬性,指向Array原型上的splice方法,對象的原型依然是Object.prototype (有什么意義)
- arguments對象的constructor是Object
- obj實例調用push方法的原理,和length相關(并不一定是類數組)
- length屬性決定了類數組的長度,push開始的位置
- 類數組轉數組:Array.prototype.slice.call(arguments)、Array.from() (分別是ES5\ES6)
- 箭頭函數沒有arguments
4-8
- finally一定執行
- throw要寫在可能會出錯的代碼段前, catch(e) 可以拋出自定義信息e
- JSON.parse()參數不能是空字符串或undefined,必須是JSON字符串
- with可以改變作用域(因此會消耗性能)
嚴格模式下不能不寫var
嚴格模式下,函數內部fn使用this指向undefined,但new fn實例化返回的this還是指向實例
嚴格模式下,函數參數不能重復
嚴格模式下,對象的屬性不能重復
嚴格模式下,eval有自己的作用域,內部用var聲明的變量不再是全局的
Duplicate property name in object literal is allowed in ES6 strict mode
常識歸類
- 1不是質數 2是
- 質數是只能被1和自己整除的數
- 斐波那契數列,前2項是1,之后每項為前兩項之和
- ASCII碼charCode范圍在0-255,每個字符1字節,從256開始的內容每個2字節
- 閏年(整除4&&不能整除100 || 整除400)
關于this
- 在函數內部,this的值取決于函數被調用的方式。this值沒被設置時(未使用call、apply)默認指向window
- call、apply傳null 和 undefined 會被轉換為全局對象。原始值如 7 或 ‘foo’ 會使用相應構造函數轉換為對象。
- bind的this綁定只生效一次:this將永久地被綁定到了bind的第一個參數
- 當函數作為對象里的方法被調用時,this 被設置為調用該函數的對象
- 當一個函數用作構造函數時(使用new關鍵字),它的this被綁定到正在構造的新對象。
- Object.assign是淺拷貝,JSON.parse(JSON.stringify)是深拷貝
// 下面的例子令人迷惑,非常危險,沒有用處。避免使用它們。
typeof new Boolean(true) === ‘object’;
typeof new Number(1) === ‘object’;
typeof new String(‘abc’) === ‘object’;
關于valueOf
JavaScript調用valueOf方法將對象轉換為原始值。
默認情況下,valueOf方法由Object后面的每個對象繼承。 每個內置的核心對象都會覆蓋此方法以返回適當的值。如果對象沒有原始值,則valueOf將返回對象本身。
JavaScript的許多內置對象都重寫了該函數,以實現更適合自身的功能需要。因此,不同類型對象的valueOf()方法的返回值和返回值類型均可能不同。
- 控制臺為什么有這樣的迷惑行為…因為自己不小心重寫了Object原型上的valueOf方法 = =,以下反面教材不要看
- 但是為什么Array、Function也受影響呢?原因是他們都是同一個valueOf
The Array prototype object does not have a valueOf property of its own;however,it inherits the valueOf property from the standard built-in Object property Object.
The Function prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype Object.
關于隱式類型轉換
關系操作符(< > ≥ ≤)
相等和不相等(== !=)
- 關系、相等運算符摻雜了其他運算符,有優先級
根據運算符優先級 ,! 的優先級是大于 == 的
ECMA類型轉換
總結
- 上一篇: ES5-19 变量声命周期、垃圾回收原理
- 下一篇: mysql 参数bug_MySQL 的这