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 函数名
复制代码
相关文章
相关标签/搜索