js高級基礎

1. 綁定多個 onclick 事件, 輸出什麼?

onclick 屬於 dom 的 Level 0 標準
普通狀況下:輸出最後一個 onclick 事件 。面試

// 只彈出 hehe
bt.onclick = () => {
  alert('haha')
}
bt.onclick = () => {
  alert('hehe')
}
複製代碼

2. 如何在一個 dom 上綁定多個 click 事件?

高級事件綁定:addEventListener
addEventListener 屬於 dom 的 Level 2 標準
注意細節:數組

  • 事件名,一概不帶on
  • 綁定事件函數中的‘this’指向綁定該事件的對象
  • 執行順序,是按綁定順序來執行的
btn.addEventListener('click',function () {
  alert(this.value) // this 指向 btn
}) // 第三個參數表明捕捉,仍是冒泡

// 先 haha ,再 hehe
btn.addEventListener('click',function () {
  alert('haha') 
}) 
btn.addEventListener('click',function () {
  alert('hehe')
}) 
複製代碼

3. 捕捉與冒泡

addEventListener:第三個參數表明捕捉仍是冒泡,默認值是false,冒泡bash

問題:點擊hd,先輸出哪一個?
閉包


// 輸出順序: b-china, b-bj,b-hd,m-hd,m-bj,m-china
china.addEventListener('click',function () {
  alert('b-china')
}, true)
bj.addEventListener('click', function () {
  alert('b-bj')
}, true) 
hd.addEventListener('click', function () {
  alert('b-hd')
}, true) 

china.addEventListener('click', function () {
  alert('m-china')
}, false)
bj.addEventListener('click', function () {
  alert('m-bj')
}, false)
hd.addEventListener('click', function () {
  alert('m-hd')
}, false) 
複製代碼

4. 中止傳播與阻止事件默認行爲

中止傳播:stopPropation
阻止事件默認行爲:preventDefaultapp

// 阻止捕捉
hd.addEventListener('click', function (ev) {
  alert('b-hd')
  ev.stopPropation()
}, true) 

// 阻止冒泡
hd.addEventListener('click', function (ev) {
  alert('b-hd')
  ev.stopPropation()
},false) 
複製代碼

問題:爲何在函數裏面 return false 不能中止傳播?
答:該函數沒有返回值。dom

5. js 做用域

不聲明變量,容易污染全局變量函數

// 第一種狀況
function t() {
   e = 6
}
t()
console.log(e) // 6
 
// 第二種狀況
e =1
function t() {
   e = 6
}
t()
console.log(e) // 6

// 第三種狀況
e =1
function t() {
  var e = 6
}
t()
console.log(e) // 1
複製代碼

6. 詞法分析

變量提高順序: 參數,var 聲明,函數聲明工具

// 輸出5
function t(age) {
  var age = 5
  console.log(age)
}
t(99) // 5

// 輸出函數
function t(greet) {
  console.log(greet) // funtion
  function greet() {
     console.log(greet) // funtion
  }
   greet()
}
t(3) // function

t1() // 1
t2() // undfined
function t1() {  // 函數聲明
  console.log(1)
}
var t2 = function () { // 函數表達式
  console.log(2)
}
複製代碼

7. arguments 對象

arguments: 長的像數組的對象post

function t(){
  console.log(arguments) // 實參
  console.log(arguments.callee) // 指向srfunction t() 
}
t(1) // [1],形參
t(1, 2) // [1, 2]
t(1, 2, 3) // [1, 2, 3]
複製代碼

問題:用遞歸來作 1,2,3...100 的和?學習

// 普通解決方案:
function sum(n) {
  if (n > 1) {
    return n + sum(n - 1)
  } else {
    return 1
  }
}
console.log(sum(100))

// 用arguments
var rs = (function (n) {
  if (n > 1) {
    return n + arguments.callee(n - 1)
  } else {
    return 1
  }
})(100)

console.log(rs)
複製代碼

8. this 指針

哪一個對象調用,this 指向誰
詳情請看:js基礎面試準備內容=>juejin.im/post/5bdae5…

9. apply 、call

apply和call都是爲了改變某個函數運行時的上下文而存在的(就是爲了改變函數內部this的指向)。
他們的經常使用用法:

  1. 數組之間的追加;
  2. 驗證是不是數組(前提是toString()方法沒有被重寫過)

    function isArray(obj){ 
        return Object.prototype.toString.call(obj) === '[object Array]' ;
    }
    複製代碼
  3. 讓類數組擁有數組的方法
    好比arguments對象,獲取到的文檔節點等,並無數組的那些方法:

  • Array.prototype.slice.apply(argument); //理論上來講這個比較快,直接在原型上查找slice方法。

  • [].slice.apply(arguments); //理論上來講這個比較慢,由於要Array作一個實例化再查找slice方法,實際上比較快,由於如今的各類自動化工具會把上一種方法轉換爲這種。

10. 閉包

var name = '11'
var obj = {
  name:'22',
  getName:function(){
    return function(){
      return this.name
    }
  }
}
console.log(obj.getName()()) // 11

// 函數閉包
function t(){
  var age = 21;
  return function () {
    console.log(age++) // 21
  }
}
var tmp = t()
var age = 1000
tmp()

// 閉包計數器
var cnt = (function(){
  var n=1;
  return function(){
    return n++
  }
})()

console.log(cnt()) // 1
console.log(cnt()) // 2
console.log(cnt()) // 3
複製代碼

11. 面向對象

用閉包來完成js面向對象之私有屬性

var Person = function() {
    var data = {
      name: 'es3',
      sex: 'male',
      age: 15
    }
    this.get = function(key) {
      return data[key]
    }
    this.set = function(key, value) {
      if (key != 'sex') {
        data[key] = value
      }
    }
  }
複製代碼

12. 原型繼承、原型冒充、複製繼承

原型繼承:prototype實現,父親是_proto__,詳情看=>js基礎面試準備內容。
特色:簡單易懂,可是沒法實現多繼承,父類新增原型方法/原型屬性,子類都能訪問到。

原型冒充:call方法

function Good() {
  this.study = function(){
    console.log('高效學習')
  }
}
function Bad() {
  Good.call(this) // 原型冒充
  this.play = function() {
    console.log('王者榮耀')
  }
}

var bad = new Bad()
bad.study()
複製代碼

特色:能夠實現多繼承,可是隻能繼承父類的實例屬性和方法,不能繼承原型屬性/方法。

複製繼承:

function Good() {
  this.study = function(){
    console.log('高效學習')
  }
}
function Bad() {
  this.play = function() {
    console.log('王者榮耀')
  }
  this.extend = function(obj) {
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        this[key] = obj[key];
      }
    }
  }
}

var bad = new Bad()
bad.extend(new Good())
bad.study()
複製代碼

13. 函數也是對象

var t = function (a,b,c) {
}
console.log(t.length) // 3 length表明函數的形參數量
console.log(t.name) // t name 函數名
複製代碼
相關文章
相關標籤/搜索