//值類型 var a=100 var b=a a=200 console.log(b) //100 //引用類型 var a={age:20} var b=a b.age=21 console.log(a.age) //21
// Numbers typeof 37 === 'number'; typeof 3.14 === 'number'; typeof Math.LN2 === 'number'; typeof Infinity === 'number'; typeof NaN === 'number'; // 儘管NaN是"Not-A-Number"的縮寫 typeof Number(1) === 'number'; // 但不要使用這種形式! // Strings typeof "" === 'string'; typeof "bla" === 'string'; typeof (typeof 1) === 'string'; // typeof老是返回一個字符串 typeof String("abc") === 'string'; // 但不要使用這種形式! // Booleans typeof true === 'boolean'; typeof false === 'boolean'; typeof Boolean(true) === 'boolean'; // 但不要使用這種形式! // Symbols typeof Symbol() === 'symbol'; typeof Symbol('foo') === 'symbol'; typeof Symbol.iterator === 'symbol'; // Undefined typeof undefined === 'undefined'; typeof declaredButUndefinedVariable === 'undefined'; typeof undeclaredVariable === 'undefined'; // Objects typeof {a:1} === 'object'; // 使用Array.isArray 或者 Object.prototype.toString.call // 區分數組,普通對象 typeof [1, 2, 4] === 'object'; typeof new Date() === 'object'; // 下面的容易使人迷惑,不要使用! typeof new Boolean(true) === 'object'; typeof new Number(1) ==== 'object'; typeof new String("abc") === 'object'; // 函數 typeof function(){} === 'function'; typeof Math.sin === 'function'; //NaN typeof 1/0 === 'NaN'; //null typeof null === 'object';
//邏輯運算符 console.log(10 & 0) //0 轉換爲true&&0 console.log(''||'abc') //abc 轉換爲false||'abc' console.log(!window.abc) //true !undefined爲true //if語句 false狀況 null '' false 0 NaN undefined //判斷一個變量是否看成true或者false var a = 100 console.log(!!a)
1.JS中使用typeof能獲得哪些類型
undefined null string number object function boolean symbol
2.什麼時候使用'===',什麼時候使用'=='
參考jQuery源碼 只有這種狀況下使用'==':javascript
if(obj.a == null) { } //這句至關於obj.a === null || obj.a === undefined
3.JS有哪些內置函數
Object Array String Number Function Boolean Date RegExp Error
4.JS變量按照存儲方式分爲哪些類型,並描述其特色
值類型、引用類型。
值類型是將變量的值存在內存中。
引用類型的變量是真實變量的指針(對象、數組、函數)。能夠無限擴張屬性。
5.如何理解JSON
是JavaScript的對象,內置兩個方法 JSON.stringify JSON.parsehtml
function Foo(name, age) { this.name = name this.age = age this.class = 'class-1' //return this 默認有這行 } var f = new Foo('zs', 20) //執行過程:1.new函數執行時this會變成空對象 2.this. 的時候賦值 3.return this 4.給f賦值 //var a = {} ===> var a = new Object() //var a =[] ===> var a = new Array() //function Foo(){} ===> var Foo = new Function() //instanceof 用於判斷一個函數是不是一個變量的構造函數
//全部的引用類型(數組、對象、函數)都具備對象特性,除了null以外,均可以自由擴展屬性 //全部的引用類型 都有__proto__ 隱式原型 //全部的函數都有 prototype 顯式原型 屬性值也是一個普通對象 //全部的引用類型(數組、對象、函數),__proto__屬性值指向它的構造函數的prototype屬性值 var obj = {}; obj.a = 100 var arr = []; arr.a = 100 function fn () {} fn.a = 100 console.log(obj.__proto__) console.log(arr.__proto__) console.log(fn.__proto__) console.log(fn.prototype) console.log(obj.__proto__ === Object.prototype) //試圖獲得一個對象的某個屬性時,若是這個對象自己沒有這個屬性,那麼會去它的__proto__(構造函數的prototype)中尋找 function Foo(name, age) { this.name = name } Foo.prototype.alertName = function () { alert(this.name) } var f = new Foo('zs') f.printName = function () { console.log(this.name) } f.printName() f.alertName()
//instanceof 是用於判斷引用類型屬於哪一個構造函數的方法 //構造函數 function Foo(name, age) { this.name = name } Foo.prototype.alertName = function () { alert(this.name) } //建立實例 var f = new Foo('zs') f.printName = function () { console.log(this.name) } f.printName() f.alertName() f.toString() // f instanceof Foo 判斷過程: // f 的 __proto__一層層往上找到是否對應Foo.prototype // 再判斷f instanceof Object
直角矩形是構造函數 圓角矩形是對象
java
var obj={ x:100, y:200, z:300 } var key for(key in obj){ //hasOwnProperty會返回一個布爾值,判斷是不是原生的屬性,以此來排除原型鏈上的屬性 if(obj.hasOwnProperty(key)){ console.log(key,obj[key]); } } //x 100 //y 200 //z 300
6.如何準確判斷一個變量是數組函數面試
var arr = [] arr instanceof Array typeof arr //object, typeof 是沒法判斷是不是數組的
7.寫一個原型鏈繼承的例子數組
function Elem(id) { this.elem = document.getElementById(id) } Elem.prototype.html = function (val) { var elem = this.elem if (val) { elem.innerHTML = val return this } else { return elem.innerHTML } } Elem.prototype.on = function (type, fn) { var elem = this.elem elem.addEventListener(type, fn) return this } var div1 = new Elem('wrapper') div1.html('<p>hello</p>').on('click', function () { alert('clicked') }).html('<p>javascript</p>')
8.描述new一個對象的過程閉包
//建立一個對象 //this指向這個對象 //執行代碼 即對this賦值 //返回this function Foo(name, age) { this.name = name this.age = age this.class = 'class-1' //return this 構造函數最好不要寫return } var f = new Foo('zs', 20)
//執行上下文:當前被執行代碼的環境/做用域 console.log(a) var a = 100 fn('zs') //函數聲明 function fn(name) { console.log(this) console.log(arguments) age = 20 console.log(name, age) var age bar(100) function bar(num) { console.log(num) } } //函數表達式: var fn = function () {} //在全局代碼執行前,會將變量定義和函數聲明先提出來 //在函數代碼執行前,會將變量定義,函數聲明,this,arguments(全部參數的集合)先提出來
//this的值執行時才能肯定 var a = { name: 'A', fn: function () { console.log(this.name) //這個階段的this沒法肯定值 } } a.fn() //this === a a.fn.call({name: 'B'}) //this === {name: 'B'} var fn1 = a.fn fn1() //this === window //做爲構造函數執行 function Foo(name) { // this = {} this.name = name // return this } var f = new Foo('zs') //做爲對象屬性執行 var obj = { name: 'A', printName: function () { console.log(this.name) //這裏this就是obj } } obj.printName //做爲普通函數執行 function fn() { console.log(this) //這裏的this就是window } fn //call apply bind function fn1(name, age) { console.log(name) console.log(this) //這裏的this是{x:100} } fn1.call({x:100}, 'zs', 20) var fn2h = function fn2(name, age) { console.log(name) console.log(this) //這裏的this是{y:200} }.bind({y:200}) fn2('zs', 20)
//不斷向父級做用域尋找變量的過程造成了做用域鏈 //沒有塊級做用域概念 if (true) { var name = 'zs' } console.log(name) //函數、全局做用域 var a = 10 function fn() { var a = 200 console.log('fn', a) } console.log('global', a) fn() var b = 100 function fn() { var c = 200 console.log(b) //當前做用域沒有定義的變量叫作自由變量 console.log(c) } fn() var a = 100 function f1() { var b = 200 function f2() { var c = 300 console.log(a) console.log(b) console.log(c) } f2() } f1() //哪一個做用域定義了f1這個函數,f1的父級做用域就是誰
//閉包應用:1.函數做爲返回值 function F1() { var a = 100 //返回一個函數 return function () { console.log(a) //100 } } //f1獲得一個函數 var f1 = F1() var a = 200 f1() //2.函數做爲參數傳遞 function F1() { var a = 100 return function() { console.log(a) //100 } } var f1 = F1() function F2(fn) { var a = 200 fn() } F2(f1)
9.說一下對變量提高的理解
變量定義、函數聲明會提早。
10.說明this幾種不一樣的使用場景
做爲構造函數、對象屬性、普通函數執行,call apply bind
11.建立10個<a>
標籤,點擊時彈出對應序號app
var i for (i = 0; i < 10; i++) { (function (i) { var a = document.createElement('a') a.innerHTML = i + '<br>' a.addEventListener('click', function (e) { e.preventDefault() alert(i) }) document.body.appendChild(a) })(i) }
12.如何理解做用域
自由變量、做用域鏈,即自由變量的尋找、閉包的兩個場景。
13.實際開發中閉包的應用
封裝變量,收斂權限 案例:函數
function isFirstLoad() { var _list = [] return function (id) { if (_list.indexOf(id) >=0) { return false } else { _list.push(id) return true } } } var firstLoad = isFirstLoad() console.log(firstLoad(10)) console.log(firstLoad(10)) console.log(firstLoad(20)) console.log(firstLoad(20))