因爲工做項目緣由,最近不多更新博客了,不過忙中抽閒,利用晚上時間,總結了一些有關JS的基礎知識,並分享一些大廠面試 題,根據知識點進行具體分析講解,但願能對方便你們來學習。 javascript
number string boolean null undefined symbol bigintjava
typeof數組
檢測出來的結果是字符串,字符串 中包含了咱們對於的數據類型
typeof null 檢測結果是 object ,不過null並不屬於對象,而是由於二進制儲存值以000開頭了,檢測對象細分類型,因此結果是「object」
瀏覽器
instanceof閉包
constructor函數
Object.prototype.toString.call([value])學習
let res = parseFloat('left:200px'); // NaN
if(res === 200) {
alert(200)
} else if (res === NaN) {
alert(NaN)
} else if(typeof res === 'number') {
alert('number') // alert輸出的結果都會轉換成字符串
} else {
alert('Invalid Number')
}
// number
複製代碼
let a = typeof typeof typeof[12, 23];
console.log(a) //string
// 解析 typeof[12, 23] => "object"
// typeof "object" => "string"
// typeof "string" => "string"
複製代碼
+ Number([val])
+ parseInt/parseFloat([val])ui
+ 加號運算的時候,若是某一邊出現字符串,則是字符串拼接
+ 把對象轉換爲數字,須要先toString()轉換爲字符串,再去轉換爲數字
+ 基於alert/confirm/prompt/document.write...這些方式輸出內容,都是把內容先轉換爲字符串,而後再輸出的
this
{}=={}:false 對象比較的是堆內存的地址
[]==[]:false
NaN==NaN:false
null==undefined:true,可是換成===結果是false(由於類型不一致),剩下null/undefined和其它任何數據類型值都不相等
字符串==對象 要把對象轉換爲字符串
剩下若是==兩邊數據類型不一致,都是須要轉換爲數字再進行比較
+ ! 轉換爲布爾值後取反
+ !! 轉換爲布爾類
+ Boolean([val])
let result = 100 + true + 21.2 + null + undefined + "Tencent" + [] + null + 9 + false;
console.log(result); // NaNTencentnull9false
/* * 隱式轉換 true 轉換爲1 null 轉換爲0 undefined 轉換爲NaN [] 轉換爲 "" */
let result2 = 10 + false + undefined + [] + 'lanfeng' + null + true + {};
// 10 + false => 10+ 0 => 10
// 10 + undefined => 10 + NaN => NaN
// NaN + [] => NaN + "" => "NaN"
// "NaN" + "lanfeng" => "NaNlanfeng"
// {} => "[object Object]"
// "NaNlanfengnulltrue[object Object]"
/* *字符串 字符串拼接 * 對象 對象+ 0 須要把對象轉換爲字符串 */
console.log([]==false);
//對象 == 布爾 都轉換成數字(隱式轉換),對象轉換成數字:先toString轉換爲字符串
//(應該是先基於valueOf獲取原始值,沒有原始值再去toString),再轉換爲數字的
// 1. [] => '' => 0
// 2. false => 0
// 0 == 0
// true
console.log(![]==false); //![]優先false, false == false true
onsole.log([]===false); // false
console.log(![]==false); //true
// ![] 把數組轉換成爲布爾類型值後,而後取反, 爲false
//false === false
// true
var a = {
i:0,
toString() {
return ++this.i
}
}
if(a==1 && a==2 && a==3) {
console.log('OK')
}
let arr = [10, 18, 0, 10, 25, 23]
arr = arr.map(parseInt)
console.log(arr)
複製代碼
對象變爲數字,應該先valueOf,沒有原始值,再toString變爲字符串,最後把字符串轉爲數字
console.log(Number('')) // 0
console.log(Number('10')) // 10
console.log(Number('10px')) // NaN 只要出現非有效數字字符串結果都是NaN
console.log(Number(true)) // 1
console.log(Number(false)) // 0
console.log(Number(null)) // 0
console.log(Number(undefined)) // NaN
複製代碼
parseInt("") //NaN
Number("") // 0
isNaN("") // 轉爲0,0是有效數字,因此結果是false
parseInt(null) // parseInt("null") ,結果是NaN
isNaN(null) // null => 0 0是有效數字,因此結果是false
parseInt("12px") // 12
Number("12px") // NaN
isNaN("12px") // true
parseFloat("1.6px") + parseInt("1.2px") + typeof parseInt(null)
// 1.6+1+"number" => 2.6+ "number" => "2.6number"
isNaN(Number(!!Number(parseInt("0.8")))) // false
// parseInt("0.8") => 0
// !!0 => false
// Number(false) => 0
// isNaN(0) => false
typeof !parseInt(null) + !isNaN(null) // "booleantrue"
// parseInt(null) => NaN
// !NaN => true
// typeof true => "boolean"
// isNaN(null) => false
// !false => true
// => "booleantrue"
複製代碼
注意:
let n = "10"
console.log(++n) // 11
console.log(+n) //10
{} + 0 // 0
// 左邊的{}認爲是一個代碼塊,不參與運算,運算只處理 +0=>0
{{}+0} //
// 參與到數學運算中"[object Object]0"
0 + {} 參與到數學運算中"0[object Object]"
複製代碼
**
var a = 0;
if (true) {
a = 1;
function a() {};
a = 21;
console.log(a)
}
console.log(a);
複製代碼
當前上下文代碼執行以前,會把var/function聲明+定義,帶var的只聲明,帶function聲明+定義,若是遇到了{}新老瀏覽器表現還好不一致(兼容ES三、ES6)
無論{},仍是一如既往的function聲明+定義,並且也不會存在塊級做用域
{}中的function,在全局下只聲明再也不定義,{} 中出現的function/let/const會建立一個塊級上下文
var x = 1;
function func(x, y = function anonymous1() {x = 2}) {
x = 3;
y();
console.log(x); // 2
}
func(5);
console.log(x); // 1
複製代碼
var x = 1;
function func(x, y = function anonymous1() {x = 2}) {
/* * EC(FUNC)私有上下文 * 做用域鏈:<EC(FUNC),EC(G)> * x=5 (2) * y=anonymous1 [[scope]]:EC(FUNC) * * EC(BLOCK) 塊級上下文 (上級上下文 EC(FUNC)) * 變量提高:var x; * 在代碼沒有執行以前,咱們會把EC(FUNC)中的值也給他一份 x=5 (3) */
var x = 3; //=>跨級上下文中的x x=3
y(); //=>不是塊級的y,向上級找, EC(FUNC)
// anonymous1執行
// 私有的上下文EC(AN) 做用域鏈:<EC(AN),EC(FUNC)>
// x=2 修改的是EC(FUNC)中的2
console.log(x); // 3
}
func(5);
console.log(x); // 1
複製代碼
ES6中存在塊級做用域(只要{} [除對象以外的大括號] 出現let/const/function)
有一種狀況也會產生
這樣在函數運行的時候,會產生兩個上下文
第一個:函數執行造成的私有上下文 EC(FUNC) =>做用域鏈/形參賦值/..
第二個:函數體大括號包起來的是一個塊級上下文 EC(BLOCK)
function Dog(name) {
this.name = name;
}
Dog.prototype.bark = function () {
console.log('wangwang');
}
Dog.prototype.sayName = function () {
console.log('my name is ' + this.name);
}
function _new(func,...args) {
//=>完成你的代碼
let obj = Object.create(func.prototype)
let result = func.call(obj, ...args)
if(result !== null && /^(object | functiion)$/.test(typeof(result))) return result
return obj
}
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=>"wangwang"
sanmao.sayName(); //=>"my name is 三毛"
console.log(sanmao instanceof Dog); //=>true
複製代碼
// 手寫call方法
~function(){
function change(context, ...args){
//=>實現你的代碼
// this -> func
context = context == undefined ? window : context;
let type = typeof context;
if (!/^(object|function)$/.test(type)) {
if (/^(symbol|bigint)$/.test(type)) {
context = Object(context);
} else {
context = new context.constructor(context);
}
}
let key = Symbol('key'),
result;
context[key] = this;
result = context[key](...args);
delete context[key];
return result;
};
Function.prototype.change=change;
}();
let obj = {name:'zhufeng'};
function func(x,y){
this.total=x+y;
return this;
}
let res = func.change(obj,100,200);
//res => {name:'zhufeng',total:300}
複製代碼
這篇文章主要分享了javascript數據類型、數據類型轉換、變量提高、閉包做用域、面向對象及一些一線面試題,若是想了解更多,請掃描二維碼,關注公衆號