摘要:但是當構造函數顯示返回一個對象時就會將這個對象賦值給變量,的使用則無效。將參數全都傳入,它會把參數作為數組傳入。
首先了解this
如果想用好這幾個方法,需要先了解this被調用方式不同而導致值不同的各種情況,然后就會認識到使用這幾個方法的原因在哪里。(可以指定this的值)
全局上下文中this指向全局對象,函數上下文this取決于被調用的方式
例:
在非嚴格模式下,全局調用函數this默認指向全局(window)
var a = 3 function exp(){ var a = 4 console.log(this.a) } var b = exp() // 輸出3
在嚴格模式下,因為this為其進入上下文時的值,所以為undefined
function exp(){ "use strict" return this } console.log(exp() === undefined) // 輸出 true
下面分析各個調用場合下this的值
作為函數被直接調用上面已經寫出了這種情況,值得注意的是,我們往往并不需要this值為window
作為方法被調用作為方法被調用時,this指向方法所在的對象上
例:
var exp = { obj: function context() { var text = "hello" return this } } console.log(exp.obj() === exp) var a = exp.obj() console.log(a === exp) var b = exp.obj console.log(b() === window) //true,,注意這里當對象的方法被全局調用后this是b的this,則是window //均輸出 true作為構造函數被調用
我們知道構造函數創建一個對象的過程
創建新對象
新對象作為this指向的對象
為新對象添加方法、屬性、、并返回對象
需要注意的地方:構造函數返回一個非對象類型時,創建新對象時并不妨礙this的使用,也會返回新創建的對象。但是當構造函數顯示返回一個對象時就會將這個對象賦值給變量,this的使用則無效。
function Fn (){ this.obj = function() { return this } } let a = new Fn() console.log(a.obj() === Fn) // false console.log(a.obj() === a) //true let newObj = { name: "小明" } function reObj (){ this.name = "康康" return newObj } let b = new reObj() console.log(b.name) //小明,返回的對象是newObj
進入正題,在這么多變化中隨時都可能出錯,所以call()、apply()、bind()就提供了一個可以指定this的方式
方法的使用
call()
這個方法接受多個參數,第一個參數是指定的this值,剩下的都是調用的函數的參數列表
fn.call(this, arg1, arg2, ...);
如果第一個參數需要是對象,如果傳入了數字、字符串、布爾值的話this會指向該原始值的自動包裝對象
function f(){ console.log(this) console.log(arguments) } f.call() // window f.call({name:"小明"}) // {name: "小明"}, [] f.call({name:"小紅"},1) // {name: "小紅"}, [1] f.call({name:"康康"},1,2) // {name: "康康"}, [1,2]
apply()
apply() 與call()區別在于第二個參數接受的是一個包含多個參數的數組,對于一些方法需要傳入的參數不能使數組,可以使用apply()調用函數使其可以使用數組作為參數。
var a = [1,2,3,4,5,6,7,8,9] sum.apply(null,a) //將參數a全都傳入,它會把參數作為數組傳入。 //求數組的最大元素 Math.max.apply(null,[1,2,6]) // 6
很多使用場景都可以被es6里的擴展運算符替代
bind()
bind()方法創建一個新的函數, 當被調用時,將其this關鍵字設置為提供的值.
this.name = "大牛" let obj = { name: "康康", age: 18, city:"上海" } let newObj = { name: "小明", sayName: function() { console.log(this.name) } } newObj.sayName()// 小明 let a = newObj.sayName.bind(obj) a() //康康 let b = newObj.sayName b() //大牛
箭頭函數
這里說一下箭頭函數,因為箭頭函數沒有this,所以會根據作用域鏈進行尋找this,這也衍生了很多用法,比如在setTimeout里經常出現的上下文(作用域)問題,如果不使用箭頭函數,在函數運行時作用域就變成了全局,使用箭頭函數會使函數里用到的this綁定在setTimeout的作用域上
var timer = { fn1() { setTimeout(function(){ console.log(this) }, 10) }, fn2() { setTimeout(()=>{ console.log(this) },20) }, fn3: ()=> { setTimeout(()=>{ console.log(this) },30) } } timer.fn1() //window timer.fn2() // timer timer.fn3() //window //第一個在執行時是在全局調用,相當于 fn1.call(undefined) // 第二個使用箭頭函數自身沒this,使this 指向了timer // 第三個自身沒this的情況下,根據箭頭函數的規則找到了最外層全局(window)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107691.html
摘要:簡單說一下的區別三者都是用于改變函數體內的指向,但是與和的最大的區別是不會立即調用,而是返回一個新函數,稱為綁定函數,其內的指向為創建它時傳入的第一個參數,而傳入的第二個及以后的參數作為原函數的參數來調用原函數。原文鏈接的區別與實現原理 1、簡單說一下bind、call、apply的區別 三者都是用于改變函數體內this的指向,但是bind與apply和call的最大的區別是:bi...
摘要:原文章發表在的個人博客一細節中函數存在定義時上下文,運行時上下文上下文是可變的為改變某個函數運行時的上下文而存在的,換句話說,是為了改變函數內部的指向沒有方法,但是有呀所以可以去把方法的運行時上下文也就是運行時的的指向,指向這個時候低啊用 原文章發表在 Klay-Clam的個人博客 一、細節 javascript 中函數存在定義時上下文,運行時上下文 上下文是可變的 1. call...
摘要:的調用者,將會指向這個對象。此外,還可以擴展自己的其他方法。的使用最后來說說。不同的是,方法的返回值是函數,并且需要稍后調用,才會執行。而和則是立即調用。總結和的主要作用,是改變對象的執行上下文,并且是立即執行的。 前言 上一篇文章 《「前端面試題系列4」this 的原理以及用法》 中,提到了 call 和 apply。 它們最主要的作用,是改變 this 的指向。在平時的工作中,除了...
摘要:返回值這段在下方應用中有詳細的示例解析。回調函數丟失的解決方案綁定回調函數的指向這是典型的應用場景綁定指向,用做回調函數。 showImg(https://segmentfault.com/img/remote/1460000019971331?w=1024&h=680); 函數原型鏈中的 apply,call 和 bind 方法是 JavaScript 中相當重要的概念,與 this...
摘要:當沒有使用而直接調用時指向對象函數和函數非常的相似,第一個參數都用來設置目標函數運行時的指向。輸出的結果為結果證明兩個地方傳入的參數都會被傳給目標函數,函數拷貝調用時傳入的參數會追加在函數調用時傳入的參數后面。 call() , apply() 與 bind() 詳解 我們知道可以用call(), apply() 和 bind()這三個函數都是用來完成函數調用,并且設置this指向。 ...
閱讀 1639·2023-04-25 20:36
閱讀 2048·2021-09-02 15:11
閱讀 1177·2021-08-27 13:13
閱讀 2653·2019-08-30 15:52
閱讀 4587·2019-08-29 17:13
閱讀 1001·2019-08-29 11:09
閱讀 1491·2019-08-26 11:51
閱讀 833·2019-08-26 10:56