1. 程式人生 > >普通函式和箭頭函式在事件中的作用域,使用不使用閉包的區別

普通函式和箭頭函式在事件中的作用域,使用不使用閉包的區別

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>22-01 高階技巧</title>
</head>

<body>
    <form method="post">
        <ul style="list-style: none;padding: 0 0;">
            <li>
                <input type="button" id="btn1" value="BTN1" />
            </li>
            <li>
                <input type="button" id="btn2" value="BTN2" />
            </li>
            <li>
                <input type="button" id="btn3" value="BTN3" />
            </li>
            <li>
                <input type="button" id="btn4" value="BTN4" />
            </li>
            <li>
                <input type="button" id="btn5" value="BTN5" />
            </li>
        </ul>
    </form>
</body>
<script type="text/javascript">
let handler = {
    message: 'event message',
    handleClick: function(event) {
        console.log(this.message);
    },
    handleClickArrow: (event) => {
        console.log(this.message);
    }
};

let btn1 = document.getElementById('btn1');

//沒用
var event = {
    message: 'window e message'
};
var message = 'w message';

//正常的函式呼叫,函式和箭頭函式的作用域,老話題了
handler.handleClick(event); //event message
handler.handleClickArrow(event); //w message

// 標準寫法,用閉包呼叫
btn1.addEventListener('click', function(event) {
    console.log(event); //MouseEvent{}
    console.log(event.type); //click

    console.log(event.currentTarget === this); //true
    console.log(event.target === this); //true

    //this指向呼叫主體
    handler.handleClick(event); //event message

    //this指向函式宣告的上級物件
    handler.handleClickArrow(event); //w message

    //this指向函式宣告的上級物件
    event.message = 'e message';
    handler.handleClickArrow(event); //w message

    //this指向函式宣告的上級物件
    this.message = 'f message';
    handler.handleClickArrow(event); //w message
}, false);

//不使用閉包的例子,作用域被修改到了btn2
let btn2 = document.getElementById('btn2');
btn2.message = 'btn2 message';
btn2.addEventListener('click', handler.handleClick, false); //btn2 message

//箭頭函式非常專一,this指向函式宣告的上級物件
let btn3 = document.getElementById('btn3');
btn3.addEventListener('click', handler.handleClickArrow, false); //w message

//通過bind限定作用域到handler
let btn4 = document.getElementById('btn4');
btn4.addEventListener('click', handler.handleClick.bind(handler), false); //event message

//箭頭函式呼叫bind也不行
let btn5 = document.getElementById('btn5');
btn5.addEventListener('click', handler.handleClickArrow.bind(handler), false); //w message
</script>

</html>

相關推薦

普通函式箭頭函式事件作用使用使用區別

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>22-01 高階技巧</title> <

js函式作用作用鏈、、立即執行函式

1.函式 定義 1.函式宣告 ```java function test(){ 函式體 }; 2.函式表示式: - 命名函式表示式 - ```java var fn = function test(){}; (匿名)函式表示式 var fn = function(){};

Javascript作用鏈與

Javascript中有兩個十分重要的概念–作用域鏈和閉包。 我是這樣理解作用域鏈的,在一個函式中,函式內部所有可以訪問的變數,排成了一個棧,想根據某個變數名訪問變數時,就從棧頂開始向下搜尋,搜到的第一個就算是找到了。那麼,這個棧是怎麼排列的呢?棧頂,是函式的內部變數

作用鏈談

重要 難點 返回 data- call 函數定義 code cee post 閉包(closure)是Javascript語言的一個難點,也是它的特色。非常多高級應用都要依靠閉包實現。 神馬是閉包 關於閉包的概念,是婆說婆有理。因而,我就翻閱了紅

JS詳細圖解作用鏈與

function 就會 挑戰 timer 重新 http 哈哈 comment bject JS詳細圖解作用域鏈與閉包 攻克閉包難題 初學JavaScript的時候,我在學習閉包上,走了很多彎路。而這次重新回過頭來對基礎知識進行梳理,要講清楚閉包,也是一個非常大的

js內存空間 執行上下文 變量對象詳解 作用鏈與 全方位解讀this

變量 詳解 tail bsp pin 上下 AR detail net 內存空間:https://blog.csdn.net/pingfan592/article/details/55189622 執行上下文:https://blog.csdn.net/pingfan592

執行環境及作用、變數物件、作用鏈、

一:執行環境及作用域 和 變數物件 執行環境是javascript中最為重要的一個概念。每個執行環境都有一個與之關聯的變數物件(儲存執行環境中所有定義的變數和函式)。二: 當代碼在執行環境中執行時,會建立一個作用域鏈。作用域鏈本質是一個指向變數物件的指標列表。

es6學習之路(2):作用存在變數提升避免暫時性死區與全域性物件的屬性脫鉤

1、ES6 新增了let命令,用來宣告變數。它的用法類似於var.        const宣告一個只讀的常量。一旦宣告,常量的值就不能改變.const宣告的變數不得改變值,這意味著, const 一旦宣告變數,就必須立即初始化,不能留到以後賦值。     這2個都是在所在

javascript深入理解-從作用鏈理解

contex num 位置 返回 ron 自由 spa 其中 alc 一、概要 紅寶書(P178)對於閉包的定義:閉包就是有權訪問另外一個函數作用域中變量的函數。 MDN,對於閉包的定義:閉包就是指能夠訪問自由變量的函數。 那麽什麽是自由變量?自由變量就是在函數中使用

js深入(三)作用鏈與

在之前我們根絕物件的原型說過了js的原型鏈,那麼同樣的js 萬物皆物件,函式也同樣存在這麼一個鏈式的關係,就是函式的作用域鏈 作用域鏈 首先先來回顧一下之前講到的原型鏈的尋找機制,就是例項會先從本身開始找,沒有的話會一級一級的網上翻,直到頂端沒有就會報一個undefined 同樣的js的機制就是這樣的,函式

es6 函式擴充套件引數作用箭頭函式

函式的擴充套件 函式引數的預設值 基本用法 ES6 之前,不能直接為函式的引數指定預設值,只能採用變通的方法。 function log(x, y = 'World') { console.log(x, y); } log('Hello

JavaScript普通函式建構函式有什麼區別

1 命名規則 建構函式名首字母一般大寫,普通函式名首字母一般小寫 2 呼叫規則 通過new操作符呼叫的則是建構函式,否則是普通函式 例: //建立函式 function Fun(par

db2left()函式right()函式對應oracle的substr()函式

DB2  LEFT、RIGHT函式  語法:LEFT(ARG,LENGTH)、RIGHT(ARG,LENGTH)  LEFT、RIGHT函式返回ARG最左邊、右邊的LENGTH個字串,ARG可以是CHAR或BINARY STRING。  eg:

linuxalarm函式pause函式詳解例項

轉載原文:https://www.cnblogs.com/yxk529188712/p/4982401.html alarm(time);執行之後告訴核心,讓核心在time秒時間之後向該程序傳送一個定時訊號,然後該程序捕獲該訊號並處理; pause()函式使該程序暫停讓出CPU,但是該函式的暫停

PHP call_user_func 函式 call_user_func_array 函式

PHP 中 call_user_func() 函式 和 call_user_func_array()函式都是回撥函式 區別: call_user_func() 可以有多個引數,第一個引數為被呼叫的回撥函式,除了第一個引數外,其他引數均為被呼叫函式的引數 c

普通函式建構函式區別

普通函式和建構函式的區別 在命名規則上,建構函式一般是首字母大寫,普通函式遵照小駝峰式命名法。 在函式呼叫的時候: function fn() { }      建構函式:1. new fn( )      

OpenCV 的split函式merge函式 及示例

就讓我們來詳細介紹一下這兩個互為冤家的函式。首先是進行通道分離的split函式。 <1>split函式詳解 將一個多通道陣列分離成幾個單通道陣列。ps:這裡的array按語境譯為陣列或者陣列。 這個split函式的C++版本有兩個原型,他們分別是: C++:

C語言 time.hclock()函式 time()函式的使用

NAME        clock - determine processor time //處理器時間處理 SYNOPSIS        #include <time

python join()函式strip() 函式 split() 函式的詳解及例項

1、join()函式 Python中有join()和os.path.join()兩個函式,具體作用如下: join(): 連線字串陣列。將字串、元組、列表中的元素以指定的字元(分隔符)連線生成一個新的字串 語法: ‘sep’.join(seq) 引數說明 sep:分隔符。可以

python的可迭代物件迭代器(iter函式next函式

iter函式: 獲取可迭代物件身上的迭代器, 會呼叫可迭代物件身上的iter的方法 next函式: 獲取迭代器中的下一個值,會呼叫迭代器物件身上的next的方法 from collections import Iterable from collections im