1. 程式人生 > >call的用法及底層實現

call的用法及底層實現

    最近也是看了很多方面的知識,前端後端都有,有的現在看起來並不是很理解,才發現有些基礎的東西其實是非常重要的,對於我們編寫高質量的程式碼,以及能夠及時找出程式碼中的bug尤為重要,博主也是看到了一個關於call方法的視訊,裡面講解的也是非常不錯,也因此深入瞭解了一下,今天和大家分享一下call方法的實現,也是對自己所學的一次鞏固。

    相信大家也是能夠了解call及apply的用法了,這裡就是簡單提及一下,最重要的作用其實就是改變this的指向,兩者之間的區別也就是傳參列表不同,call的引數是單獨的一個一個傳,而apply是傳進去一個數組,但是其實解析的時候,也是會將陣列的元素抽出來一個一個解析,要注意的是,即使apply只有一個引數,也需要加上[],表示陣列形式的引數。上面的說法可能有些難以理解,至少當初對於博主來說,一直沒有能理解,後來還是看到了一個博文,覺得上面的解釋非常有意思:即我有一個吃的方法,加入某人也想要我的吃的方法,但是他自己沒有,那麼他怎麼辦才能獲得吃的方法呢,很簡答,就是利用call方法。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script>
		var person = {
			name: 'qiugu',
			eat: function(){
				console.log('i am eating');
			}
		}

		var personAnother = {
			name: 'gailun',
			drink: function(){
				console.log('i am drinking');
			}
		}

		var result = person.eat.call(personAnother);    //i am eating

	</script>
</body>
</html>

最後輸出的結果就是吃的方法,更通俗的來說,就是有了call方法以後,等於自己擁有了別人的能力,這樣一說是不是更能理解了呢。

    當然今天主要是來實現一下call方法的,當然其實apply也是一樣的原理,這裡就是以call方法為例,有興趣的同學可以試試apply的實現,瞭解底層的實現方法,才能更好的去運用起來,下面則是實現的過程

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script>
		Function.prototype.myCall = function(context){
			context = context || window;   
			context.fn = this;    //context指的就是傳進去的引數,這裡其實就是指的就是呼叫的物件,即another
			var args = [],result;    //this指的是上下文的環境,這裡就是指的eat的方法,即在another物件上建立了eat的方法
			for(let i = 1;i < arguments.length;i++){
				args.push(arguments[i]);
			}
			result = context.fn(...args);
			delete context.fn;
			return result;
		}

		var person = {
			name: 'qiugu',
			eat: function(){
				console.log('eating!');
			}
		}

		var another = {
			name: 'yasuo',
			drink: function(){
				console.log('drinking!');
			}
		}

		person.eat.myCall(another);//eating!
	</script>
</body>
</html>

    這個其實就是在Function的原型上面寫了一個方法,實際過程就是在指向的物件上面建立了一個同樣的方法,然後再將這個方法刪掉,之所以有context = context || window這樣的寫法,其實就是一個防止報錯的寫法,如果輸入的context為空的話,就用window這個全域性變數來指代context,當然最後輸出的結果也就是undefined了,不過卻不會報錯,這種寫法也是給了博主這樣的菜鳥一個很大的榜樣,寫程式碼就是要這樣,考慮周全,要想好思路,確定好以後再去寫,任何值如果不注意的話,後續產生bug,找都很難找出來。希望菜鳥程式設計師們後期寫程式碼也是要以此為榜樣,養成一個良好的習慣比什麼都重要。大笑

相關推薦

call用法底層實現

    最近也是看了很多方面的知識,前端後端都有,有的現在看起來並不是很理解,才發現有些基礎的東西其實是非常重要的,對於我們編寫高質量的程式碼,以及能夠及時找出程式碼中的bug尤為重要,博主也是看到了一個關於call方法的視訊,裡面講解的也是非常不錯,也因此深入瞭解了一下,今

Redis五種資料型別底層實現

Redis物件型別簡介 Redis是一種key/value型資料庫,其中,每個key和value都是使用物件表示的。比如,我們執行以下程式碼: redis>SET message "hello redis" 其中的key是message,是一個包含了字串"mess

STL中map、set的資料結構底層實現

本文分析了STL的map和set vector(向量)——STL中標準而安全的陣列。只能在vector 的“前面”增加資料。 deque(雙端佇列double-ended queue)——在功能上和vector相似,但是可以在前後兩端向其中新增資料。  list(列表)——遊標

迭代器Iterator操作底層實現

Iterator使用 package com.gcx.demo; import java.util.ArrayList; import java.util.HashMap; import jav

vue三要素底層實現機制

深入解析Vue 我們首先來熟悉一下我們這個文件所學習內容的流程。   先對比一下jQuery和Vue的區別,再講述Vue的MVVM模型,接著講解Vue的實現流程。   當然,我是不相信沒有對比哪來的傷害,沒有傷害哪能讓人記憶深入骨髓咧,向來都是被傷害過的人我才會記得你,我要恨你一

linux--fork()函式詳解底層實現機制

fork底層實現機制:Linux中實現為呼叫clone函式,然後為do_fork,再然後copy_process()複製程序(複製相應資料結構例如:核心棧、thread_info、task_

深入理解HashMap底層實現

概述:HashMap是我們常用的一種集合類,資料以鍵值對的形式儲存。我們可以在HashMap中儲存指定的key,value鍵值對;也可以根據key值從HashMap中取出相應的value值;也可以通過keySet方法返回key檢視進行迭代。以上是基於HashMap的常見應用,但是光會使用是遠

Java併發核心基礎——執行緒池使用底層實現機制詳解

Java執行緒池概述: 從使用入手: java.util.concurrent.Executosr是執行緒池的靜態工廠,我們通常使用它方便地生產各種型別的執行緒池,主要的方法有三種: 1、newS

inet_pton函式和inet_ntop函式的用法簡單實現

        這兩個函式是隨IPv6出現的新函式,對於IPv4地址和IPv6地址都適用。函式名中的p和n非別代表表達(presentation)和數值(numeric)。地址的表達格式通常是ASCII字串,數值格式則是存放到套接字地址結構中的二進位制值。函式如下: #i

HashMap和HashSet原理底層實現

HashMap底層用雜湊演算法實現,下面看一下雜湊算表的整體概括: 當map.put(“key”,”values”);的時候,底層是這樣的: static final Entry<?,?>[] EMPTY_TABLE = {}; transient E

killkill -9的用法如何實現程序的優雅退出

 kill pid與kill -9 pid的區別         kill pid的作用是向程序號為pid的程序傳送SIGTERM(這是kill預設傳送的訊號),該訊號是一個結束程序的訊號且可以被應用程式捕獲。若應用程式沒有捕獲並響應該訊號的邏輯程式碼,則該訊號的預設動

javascript call用法好處

javascipt 中 Call的用法及好處 javascript call可以改變當前函式的作用域, 基本用法如下 function Person(name){ this.name = name; } Person.prototype.say

Spring原始碼分析之IOC的三種常見用法原始碼實現(二)

Spring原始碼分析之IOC的三種常見用法及原始碼實現(二) 回顧上文 我們研究的是 AnnotationConfigApplicationContext annotationConfigApplication = new AnnotationConfigApplicationContext

STL一些容器底層實現機制

失效 list容器 容量 較高的 浪費 復制 處理 跳轉 strong 1、vector容器 vector的數據安排以及操作方式,與數組類似。倆這唯一的區別就是空間的運用靈活性。數組是靜態空間,一旦配置了就不能改變,vector是動態數組。在堆上分配內存。vector是動態

memcpy,memmove,memset函數福彩3D平臺搭建用法實現

平臺搭建 內存 例如 oid res mem con ems 講解 一.函數介紹:福彩3D平臺搭建論壇:haozbbs.com Q14465950671、memcpy函數原型:extern void memcpy(void dest, const void *src, si

atoi函式的用法用C語言實現ato

庫函式原型: #inclue <stdlib.h> int atoi(const char *nptr); 用法:將字串裡的數字字元轉化為整形數。返回整形值。 注意:轉化時跳過前面的空格字元,直到遇上數字或正負符號才開始做轉換,而再遇到非數字或字串結束時('/0')才結束

HashMap原始碼實現原理底層結構

Java為資料結構中的對映定義了一個介面java.util.Map,此介面主要有四個常用的實現類,分別是HashMap、Hashtable、LinkedHashMap和TreeMap。 HashMap:HashMap是陣列+連結串列實現的,它根據鍵的hashCode值儲存資料,大多數情況下可

HashMap的實現原理底層結構

雜湊表(hash table)也叫散列表,是一種非常重要的資料結構,應用場景及其豐富,許多快取技術(比如memcached)的核心其實就是在記憶體中維護一張大的雜湊表,而HashMap的實現原理也常常出現在各類的面試題中,重要性可見一斑。本文會對java集合框架中的對應實現H

ArrayList工作原理底層原始碼實現

一.概述 以陣列實現。節約空間,但陣列有容量限制。超出限制時會增加50%容量,用System.arraycopy()複製到新的陣列。因此最好能給出陣列大小的預估值。預設第一次插入元素時建立大小為10的陣列。 按陣列下標訪問元素-get(i)、set(i,e) 的效能很高,這是陣列的基本優勢。

redis del與unlink命令用法實現

1. DEL 命令   DEL key [key ...] 刪除指定的一批keys,如果刪除中的某些key不存在,則直接忽略。 返回值 integer-reply: 被刪除的keys的數量 例子 redis> SET ke