這次帶給大家javascript中call詳解,使用javascript中call的注意事項有哪些,下面就是實戰案例,一起來看一下。
首先要先了解函數本身會有一些自己的屬性,例如:
length:形參的數量;
name:函數名稱;
prototype:類別的原型,原型上定義的方法都是目前這個類別的實例的公有方法;
proto:把函數當作一個普通對象,指向Function這個類別的原型
函數在整個JavaScript中是最複雜也是最重要的知識,對於一個函數來說,會存在多種角色:
function Fn() { var num = 500; this.x = 100; } Fn.prototype.getX = function () { console.log(this.x); } Fn.aaa = 1000;var f = new Fn; f.num // undefinedf.aaa // undefined12345678910111213 var res = Fn(); // res是undefined Fn中的this是window
角色一:普通函數,對於Fn而言,它本身是一個普通的函數,執行的時候會形成私有的作用域,然後進行形參賦值、預解析、程式碼執行、執行完成後記憶體銷毀;
角色二:類,它有自己的實例,f就是Fn作為類別而產生的一個實例,也有一個叫做prototype的屬性是自己的原型,它的實例都可以指向自己的原型;
角色三:普通對象,Fn和var obj = {} 中的obj一樣,就是一個普通的物件(所有的函數都是Function的實例),它作為物件可以有一些自己的私有屬性,也可以透過proto找到Function.prototype;
函數的以上三種角色,可能大多數同學對於角色一和角色二都是沒有任何疑問的,不過對於角色三可能會稍有疑惑,那麼畫張圖來理解下吧:
函數作為普通對象.png
call深入
call的基本使用
var ary = [12, 23, 34]; ary.slice();
以上兩行簡單的程式碼的執行過程為:ary這個實例透過原型鏈的尋找機制找到Array .prototype上的slice方法,讓找到的slice方法執行,在執行slice方法的過程中才把ary數組進行了截取。
注意:slice方法執行之前有一個在原型上尋找的過程(目前實例中沒有找到,再根據原型鏈查找)。
當知道了一個物件呼叫方法會有一個查找過程之後,我們再看:
var obj = {name:’iceman’}; function fn() { console.log(this); console.log(this.name); } fn(); // this –> window // obj.fn(); // Uncaught TypeError: obj.fn is not a function fn.call(obj);
call方法的作用:先尋找call方法,最後透過原型鏈在Function的原型中找到call方法,然後讓call方法執行,在執行call方法的時候,讓fn方法中的this變成第一個參數值obj,最後再把fn這個函數執行。
2.2、call方法原理
模擬Function中內建的call方法,寫一個myCall方法,探討call方法的執行原理
function sum(){ console.log(this); }function fn(){ console.log(this); }var obj = {name:'iceman'};Function.prototype.myCall = function (context) { // myCall方法中的this就是当前我要操作和改变其this关键字的那个函数名 // 1、让fn中的this关键字变为context的值->obj // 让this这个函数中的"this关键字"变为context // eval(this.toString().replace("this","obj")); // 2、让fn方法在执行 // this();};1234567891011121314151617
#fn.myCall( obj);// myCall方法中原來的this是fn
sum.myCall(obj);// myCall方法中原來的this是sum
當fn.myCall(obj); 這行程式碼執行的時候,根據this的尋找規律,在myCall方法前面有”.”,那麼myCall中的this就是fn。執行myCall的方法,在第一步會將方法體中this換為傳入的對象,並且執行原來的this, 注意:是執行原來的this(我在學這一塊的時候這裡理解了好久),在本例中就是執行fn。
看完以上那段話是不是有些懵逼了呢?哈哈,沒事,接下來看下面例子,理解一下。
call方法經典範例
function fn1() { console.log(1); }function fn2() { console.log(2); }123456
輸出一
fn1.call(fn2); // 1
首先fn1透過原型鏈尋找機制找到Function.prototype上的call方法,並且讓call方法執行,此時call這個方法中的this就是要操作的fn1。在call方法程式碼執行的過程過程中,先讓fn1中的「this關鍵字」變成fn2,然後再讓fn1這個方法執行。
注意:在執行call方法的時候,fn1中的this的確會變成fn2,但是在fn1的方法體中輸出的內容中並沒有涉及到任何和this相關的內容,所以還是輸出1.
輸出二
fn1.call.call(fn2); // 2
首先fn1透過原型鏈找到Function.prototype上的call方法,然後再讓call方法透過原型再找到Function原型上的call(因為call本身的值也是函數,所以同樣可以讓Function.prototype),在第二次找到call的時候再讓方法執行,方法中的this是fn1.call,先讓這個方法中的this變成fn2,然後再讓fn1.call執行。
這個例子有點繞了,不過一步一步來理解。在最開始的時候,fn1.call.call(fn2) 這行程式碼的最後一個call中的this是fn1.call,根據前面的理解可以知道fn1.call 的原理大致為:
Function.prototype.call = function (context) { // 改变fn中的this关键字 // eval(....); // 让fn方法执行 this(); // 此时的this就是fn1};1234567
將上面的程式碼寫為另一種形式:
Function.prototype.call = test1;function test1 (context) { // 改变fn中的this关键字 // eval(....); // 让fn方法执行 this(); // 此时的this就是fn1};12345678
我們知道,這兩種形式的寫法的作用是一樣的。那麼此時可以將 fn1.call.call(fn2) 寫成 test1.call(fn2) ,call中的的this就是test1:
Function.prototype.call = function (context) { // 改变fn中的this关键字 // eval(....); // 让fn方法执行 this(); // 此时的this就是test1};1234567
注意:此時call中的的this就是test1。
然後再將call中this替換為fn2,那麼test1方法變成:
Function.prototype.call = function (context) { // 省略其他代码 fn2(); };12345
所以最后是fn2执行,所以最后输出2。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是javascript中call詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。