onclick 屬於 dom 的 Level 0 標準
普通狀況下:輸出最後一個 onclick 事件 。面試
// 只彈出 hehe
bt.onclick = () => {
alert('haha')
}
bt.onclick = () => {
alert('hehe')
}
複製代碼
高級事件綁定:addEventListener
addEventListener 屬於 dom 的 Level 2 標準
注意細節:數組
btn.addEventListener('click',function () {
alert(this.value) // this 指向 btn
}) // 第三個參數表明捕捉,仍是冒泡
// 先 haha ,再 hehe
btn.addEventListener('click',function () {
alert('haha')
})
btn.addEventListener('click',function () {
alert('hehe')
})
複製代碼
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)
複製代碼
中止傳播: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
不聲明變量,容易污染全局變量函數
// 第一種狀況
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
複製代碼
變量提高順序: 參數,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)
}
複製代碼
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)
複製代碼
哪一個對象調用,this 指向誰
詳情請看:js基礎面試準備內容=>juejin.im/post/5bdae5…
apply和call都是爲了改變某個函數運行時的上下文而存在的(就是爲了改變函數內部this的指向)。
他們的經常使用用法:
驗證是不是數組(前提是toString()方法沒有被重寫過)
function isArray(obj){
return Object.prototype.toString.call(obj) === '[object Array]' ;
}
複製代碼
讓類數組擁有數組的方法
好比arguments對象,獲取到的文檔節點等,並無數組的那些方法:
Array.prototype.slice.apply(argument); //理論上來講這個比較快,直接在原型上查找slice方法。
[].slice.apply(arguments); //理論上來講這個比較慢,由於要Array作一個實例化再查找slice方法,實際上比較快,由於如今的各類自動化工具會把上一種方法轉換爲這種。
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
複製代碼
用閉包來完成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
}
}
}
複製代碼
原型繼承: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()
複製代碼
var t = function (a,b,c) {
}
console.log(t.length) // 3 length表明函數的形參數量
console.log(t.name) // t name 函數名
複製代碼