面試官問:JS的this指向

寫于2018年12月25日,發布在掘金上閱讀量近一萬,現在發布到微信公眾號申明原創。

前言

這是面試官問系列的第四篇,旨在幫助讀者提升JS基礎知識,包含new、call、apply、this、繼承相關知識。
面試官問系列文章如下:感興趣的讀者可以點擊閱讀。
1.面試官問:能否模擬實現JS的new操作符
2.面試官問:能否模擬實現JS的bind方法
3.面試官問:能否模擬實現JS的call和apply方法
4.面試官問:JS的this指向
5.面試官問:JS的繼承

面試官出很多考題,基本都會變著方式來考察this指向,看候選人對JS基礎知識是否扎實。讀者可以先拉到底部看總結,再谷歌(或各技術平臺)搜索幾篇類似文章,看筆者寫的文章和別人有什么不同(歡迎在評論區評論不同之處),對比來看,驗證與自己現有知識是否有盲點,多看幾篇,自然就會完善自身知識。

附上之前寫文章寫過的一段話:已經有很多關于this的文章,為什么自己還要寫一遍呢。學習就好比是座大山,人們沿著不同的路登山,分享著自己看到的風景。你不一定能看到別人看到的風景,體會到別人的心情。只有自己去登山,才能看到不一樣的風景,體會才更加深刻。

函數的this在調用時綁定的,完全取決于函數的調用位置(也就是函數的調用方法)。為了搞清楚this的指向是什么,必須知道相關函數是如何調用的。

全局上下文

非嚴格模式和嚴格模式中this都是指向頂層對象(瀏覽器中是window)。

this === window // true
'use strict'
this === window;
this.name = '若川';
console.log(this.name); // 若川

函數上下文

普通函數調用模式

// 非嚴格模式
var name = 'window';
var doSth = function(){console.log(this.name);
}
doSth(); // 'window'

你可能會誤以為window.doSth()是調用的,所以是指向window。雖然本例中window.doSth確實等于doSthname等于window.name。上面代碼中這是因為在ES5中,全局變量是掛載在頂層對象(瀏覽器是window)中。事實上,并不是如此。

// 非嚴格模式
let name2 = 'window2';
let doSth2 = function(){console.log(this === window);console.log(this.name2);
}
doSth2() // true, undefined

這個例子中let沒有給頂層對象中(瀏覽器是window)添加屬性,window.name2和window.doSth都是undefined

嚴格模式中,普通函數中的this則表現不同,表現為undefined

// 嚴格模式
'use strict'
var name = 'window';
var doSth = function(){console.log(typeof this === 'undefined');console.log(this.name);
}
doSth(); // true,// 報錯,因為this是undefined

看過的《你不知道的JavaScript》上卷的讀者,應該知道書上將這種叫做默認綁定。對callapply熟悉的讀者會類比為:

doSth.call(undefined);
doSth.apply(undefined);

效果是一樣的,callapply作用之一就是用來修改函數中的this指向為第一個參數的。第一個參數是undefined或者null,非嚴格模式下,是指向window。嚴格模式下,就是指向第一個參數。后文詳細解釋。
經常有這類代碼(回調函數),其實也是普通函數調用模式。

var name = '若川';
setTimeout(function(){console.log(this.name);
}, 0);
// 語法
setTimeout(fn | code, 0, arg1, arg2, ...)
// 也可以是一串代碼。也可以傳遞其他函數
// 類比 setTimeout函數內部調用fn或者執行代碼`code`。
fn.call(undefined, arg1, arg2, ...);

對象中的函數(方法)調用模式

var name = 'window';
var doSth = function(){console.log(this.name);
}
var student = {name: '若川',doSth: doSth,other: {name: 'other',doSth: doSth,}
}
student.doSth(); // '若川'
student.other.doSth(); // 'other'
// 用call類比則為:
student.doSth.call(student);
// 用call類比則為:
student.other.doSth.call(other);

但往往會有以下場景,把對象中的函數賦值成一個變量了。這樣其實又變成普通函數了,所以使用普通函數的規則(默認綁定)。

var studentDoSth = student.doSth;
studentDoSth(); // 'window'
// 用call類比則為:
studentDoSth.call(undefined);

call、apply、bind 調用模式

上文提到callapply,這里詳細解讀一下。先通過MDN認識下callapplyMDN 文檔:Function.prototype.call()
語法

fun.call(thisArg, arg1, arg2, ...)

thisArg
fun函數運行時指定的this值。需要注意的是,指定的this值并不一定是該函數執行時真正的this值,如果這個函數處于非嚴格模式下,則指定為nullundefinedthis值會自動指向全局對象(瀏覽器中就是window對象),同時值為原始值(數字,字符串,布爾值)的this會指向該原始值的自動包裝對象。
arg1, arg2, ...
指定的參數列表
返回值
返回值是你調用的方法的返回值,若該方法沒有返回值,則返回undefined
applycall類似。只是參數不一樣。它的參數是數組(或者類數組)。

根據參數thisArg的描述,可以知道,call就是改變函數中的this指向為thisArg,并且執行這個函數,這也就使JS靈活很多。嚴格模式下,thisArg是原始值是值類型,也就是原始值。不會被包裝成對象。舉個例子:

var doSth = function(name){console.log(this);console.log(name);
}
doSth.call(2, '若川'); // Number{2}, '若川'
var doSth2 = function(name){'use strict';console.log(this);console.log(name);
}
doSth2.call(2, '若川'); // 2, '若川'

雖然一般不會把thisArg參數寫成值類型。但還是需要知道這個知識。之前寫過一篇文章:面試官問:能否模擬實現JScallapply方法就是利用對象上的函數this指向這個對象,來模擬實現callapply的。感興趣的讀者思考如何實現,再去看看筆者的實現。

bindcallapply類似,第一個參數也是修改this指向,只不過返回值是新函數,新函數也能當做構造函數(new)調用。MDN Function.prototype.bind

bind()方法創建一個新的函數, 當這個新函數被調用時this鍵值為其提供的值,其參數列表前幾項值為創建時指定的參數序列。
語法:fun.bind(thisArg[, arg1[, arg2[, ...]]])
參數:thisArg調用綁定函數時作為this參數傳遞給目標函數的值。如果使用new運算符構造綁定函數,則忽略該值。當使用bindsetTimeout中創建一個函數(作為回調提供)時,作為thisArg傳遞的任何原始值都將轉換為object。如果沒有提供綁定的參數,則執行作用域的this被視為新函數的thisArgarg1, arg2, ...當綁定函數被調用時,這些參數將置于實參之前傳遞給被綁定的方法。返回值返回由指定的this值和初始化參數改造的原函數拷貝。

之前也寫過一篇文章:面試官問:能否模擬實現JSbind方法就是利用callapply指向這個thisArg參數,來模擬實現bind的。感興趣的讀者思考如何實現,再去看看筆者的實現。

構造函數調用模式

function Student(name){this.name = name;console.log(this); // {name: '若川'}// 相當于返回了// return this;
}
var result = new Student('若川');

使用new操作符調用函數,會自動執行以下步驟。

  1. 創建了一個全新的對象。

  2. 這個對象會被執行[[Prototype]](也就是__proto__)鏈接。

  3. 生成的新對象會綁定到函數調用的this

  4. 通過new創建的每個對象將最終被[[Prototype]]鏈接到這個函數的prototype對象上。

  5. 如果函數沒有返回對象類型Object(包含Functoin, Array, Date, RegExg, Error),那么new表達式中的函數調用會自動返回這個新的對象。

由此可以知道:new操作符調用時,this指向生成的新對象。特別提醒一下,new調用時的返回值,如果沒有顯式返回對象或者函數,才是返回生成的新對象

function Student(name){this.name = name;// return function f(){};// return {};
}
var result = new Student('若川');
console.log(result); {name: '若川'}
// 如果返回函數f,則result是函數f,如果是對象{},則result是對象{}

很多人或者文章都忽略了這一點,直接簡單用typeof判斷對象。雖然實際使用時不會顯示返回,但面試官會問到。

之前也寫了一篇文章面試官問:能否模擬實現JSnew操作符,是使用apply來把this指向到生成的新生成的對象上。感興趣的讀者思考如何實現,再去看看筆者的實現。

原型鏈中的調用模式

function Student(name){this.name = name;
}
var s1 = new Student('若川');
Student.prototype.doSth = function(){console.log(this.name);
}
s1.doSth(); // '若川'

會發現這個似曾相識。這就是對象上的方法調用模式。自然是指向生成的新對象。如果該對象繼承自其它對象。同樣會通過原型鏈查找。上面代碼使用ES6class寫法則是:

class Student{constructor(name){this.name = name;}doSth(){console.log(this.name);}
}
let s1 = new Student('若川');
s1.doSth();

babel es6轉換成es5的結果,可以去babeljs網站轉換測試自行試試。

'use strict';var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var Student = function () {function Student(name) {_classCallCheck(this, Student);this.name = name;}_createClass(Student, [{key: 'doSth',value: function doSth() {console.log(this.name);}}]);return Student;
}();var s1 = new Student('若川');
s1.doSth();

由此看出,ES6class也是通過構造函數模擬實現的,是一種語法糖。

箭頭函數調用模式

先看箭頭函數和普通函數的重要區別:

1、沒有自己的thissuperargumentsnew.target綁定。2、不能使用new來調用。3、沒有原型對象。4、不可以改變this的綁定。5、形參名稱不能重復。

箭頭函數中沒有this綁定,必須通過查找作用域鏈來決定其值。如果箭頭函數被非箭頭函數包含,則this綁定的是最近一層非箭頭函數的this,否則this的值則被設置為全局對象。比如:

var name = 'window';
var student = {name: '若川',doSth: function(){// var self = this;var arrowDoSth = () => {// console.log(self.name);console.log(this.name);}arrowDoSth();},arrowDoSth2: () => {console.log(this.name);}
}
student.doSth(); // '若川'
student.arrowDoSth2(); // 'window'

其實就是相當于箭頭函數外的this是緩存的該箭頭函數上層的普通函數的this。如果沒有普通函數,則是全局對象(瀏覽器中則是window)。也就是說無法通過callapplybind綁定箭頭函數的this(它自身沒有this)。而callapplybind可以綁定緩存箭頭函數上層的普通函數的this。比如:

var student = {name: '若川',doSth: function(){console.log(this.name);return () => {console.log('arrowFn:', this.name);}}
}
var person = {name: 'person',
}
student.doSth().call(person); // '若川'  'arrowFn:' '若川'
student.doSth.call(person)(); // 'person' 'arrowFn:' 'person'

DOM事件處理函數調用

addEventerListener、attachEvent、onclick

<button class="button">onclick</button>
<ul class="list"><li>1</li><li>2</li><li>3</li>
</ul>
<script>var button = document.querySelector('button');button.onclick = function(ev){console.log(this);console.log(this === ev.currentTarget); // true}var list = document.querySelector('.list');list.addEventListener('click', function(ev){console.log(this === list); // trueconsole.log(this === ev.currentTarget); // trueconsole.log(this);console.log(ev.target);}, false);
</script>

onclickaddEventerListener是指向綁定事件的元素。一些瀏覽器,比如IE6~IE8下使用attachEventthis指向是window。順便提下:面試官也經常考察ev.currentTargetev.target的區別。ev.currentTarget是綁定事件的元素,而ev.target是當前觸發事件的元素。比如這里的分別是ulli。但也可能點擊的是ul,這時ev.currentTargetev.target就相等了。

內聯事件處理函數調用

<button class="btn1" onclick="console.log(this === document.querySelector('.btn1'))">點我呀</button>
<button onclick="console.log((function(){return this})());">再點我呀</button>

第一個是button本身,所以是true,第二個是window。這里跟嚴格模式沒有關系。當然我們現在不會這樣用了,但有時不小心寫成了這樣,也需要了解。

其實this的使用場景還有挺多,比如對象object中的gettersetterthisnew Function()eval。但掌握以上幾種,去分析其他的,就自然迎刃而解了。使用比較多的還是普通函數調用、對象的函數調用、new調用、call、apply、bind調用、箭頭函數調用。那么他們的優先級是怎樣的呢。

優先級

而箭頭函數的this是上層普通函數的this或者是全局對象(瀏覽器中是window),所以排除,不算優先級。

var name = 'window';
var person = {name: 'person',
}
var doSth = function(){console.log(this.name);return function(){console.log('return:', this.name);}
}
var Student = {name: '若川',doSth: doSth,
}
// 普通函數調用
doSth(); // window
// 對象上的函數調用
Student.doSth(); // '若川'
// call、apply 調用
Student.doSth.call(person); // 'person'
new Student.doSth.call(person);

試想一下,如果是Student.doSth.call(person)先執行的情況下,那new執行一個函數。是沒有問題的。然而事實上,這代碼是報錯的。運算符優先級是new比點號低,所以是執行new (Student.doSth.call)(person)Function.prototype.call,雖然是一個函數(applybind也是函數),跟箭頭函數一樣,不能用new調用。所以報錯了。

Uncaught TypeError: Student.doSth.call is not a constructor

這是因為函數內部有兩個不同的方法:[[Call]][[Constructor]]。當使用普通函數調用時,[[Call]]會被執行。當使用構造函數調用時,[[Constructor]]會被執行。callapplybind和箭頭函數內部沒有[[Constructor]]方法。

從上面的例子可以看出普通函數調用優先級最低,其次是對象上的函數。call(apply、bind)調用方式和new調用方式的優先級,在《你不知道的JavaScript》是對比bindnew,引用了mdnbindployfill實現,new調用時bind之后的函數,會忽略bind綁定的第一個參數,(mdn的實現其實還有一些問題,感興趣的讀者,可以看我之前的文章:面試官問:能否模擬實現JSbind方法),說明new的調用的優先級最高。所以它們的優先級是new 調用 > call、apply、bind 調用 > 對象上的函數調用 > 普通函數調用。

總結

如果要判斷一個運行中函數的 this 綁定, 就需要找到這個函數的直接調用位置。找到之后 就可以順序應用下面這四條規則來判斷 this 的綁定對象。

  1. new 調用:綁定到新創建的對象,注意:顯示return函數或對象,返回值不是新創建的對象,而是顯式返回的函數或對象。

  2. call 或者 apply( 或者 bind) 調用:嚴格模式下,綁定到指定的第一個參數。非嚴格模式下,nullundefined,指向全局對象(瀏覽器中是window),其余值指向被new Object()包裝的對象。

  3. 對象上的函數調用:綁定到那個對象。

  4. 普通函數調用:在嚴格模式下綁定到 undefined,否則綁定到全局對象。

ES6 中的箭頭函數:不會使用上文的四條標準的綁定規則, 而是根據當前的詞法作用域來決定this, 具體來說, 箭頭函數會繼承外層函數,調用的 this 綁定( 無論 this 綁定到什么),沒有外層函數,則是綁定到全局對象(瀏覽器中是window)。這其實和 ES6 之前代碼中的 self = this 機制一樣。

DOM事件函數:一般指向綁定事件的DOM元素,但有些情況綁定到全局對象(比如IE6~IE8attachEvent)。

一定要注意,有些調用可能在無意中使用普通函數綁定規則。如果想“ 更安全” 地忽略 this 綁 定, 你可以使用一個對象, 比如? = Object.create(null), 以保護全局對象。

面試官考察this指向就可以考察new、call、apply、bind,箭頭函數等用法。從而擴展到作用域、閉包、原型鏈、繼承、嚴格模式等。這就是面試官樂此不疲的原因。

讀者發現有不妥或可改善之處,歡迎指出。另外覺得寫得不錯,可以點個贊,也是對筆者的一種支持。

學習源碼整體架構系列

1.學習 jQuery 源碼整體架構,打造屬于自己的 js 類庫
2.學習 underscore 源碼整體架構,打造屬于自己的函數式編程類庫
3.學習 lodash 源碼整體架構,打造屬于自己的函數式編程類庫
4.學習 sentry 源碼整體架構,打造屬于自己的前端異常監控SDK
5.學習 vuex 源碼整體架構,打造屬于自己的狀態管理庫
6.學習 axios 源碼整體架構,打造屬于自己的請求庫

微信公眾號

作者:常以若川為名混跡于江湖。前端路上 | PPT 愛好者 | 所知甚少,唯善學。博客:https://lxchuan12.cn/posts/,閱讀體驗可能更好些。

若川視野

主要發布前端 | PPT | 生活 | 效率相關的文章,長按掃碼關注。歡迎加我微信lxchuan12(注明來源,基本來者不拒),拉您進【前端視野交流群】,長期交流學習~

小提醒:若川視野公眾號原創文章合集在菜單欄中間【原創精選】按鈕,歡迎點擊閱讀

由于公眾號限制外鏈,點擊讀原文,或許閱讀體驗更佳,覺得文章不錯,可以點個在看呀^_^另外歡迎留言交流~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276465.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276465.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276465.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS實現div懸浮框的代碼(兼容IE6)

轉載鏈接&#xff1a;http://hi.baidu.com/grayworm/item/b735c2061f4e33ea34990265 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://ww…

python數組替換_Python:替換數組中的值

我會按照以下思路做些事情&#xff1a;import numpy as npdef fill(arr, fwd_fill):out arr.copy()if fwd_fill:start, end, step 0, len(out), 1else:start, end, step len(out)-1, -1, -1cur out[start]for i in range(start, end, step):if np.isnan(out[i]):out[i] cu…

(原創) 如何在Ubuntu設定P7010的1280 x 768解析度? (OS) (Linux) (Ubuntu) (NB) (P7010)

AbstractFujitsu P7010唯一較特別的硬體規格就是1280 x 768的解析度&#xff0c;無論任何Linux distribution預設都只能抓到1024 x 768&#xff0c;該如何才能抓到最佳的1280 x 768呢?IntroductionP7010非常適合Linux&#xff0c;但唯一的遺憾就是1280 x 768解析度不被支援&am…

python的常量和變量_python變量和常量

變量什么是變量&#xff1f;變量&#xff0c;是用于在內存中存放程序數據的容器計算機的最核心功能就是“計算”&#xff0c; 計算需要數據源&#xff0c;數據源要存在內存里&#xff0c;比如我要把小明的姓名、身高、年齡信息存下來&#xff0c;后面程序會調用。怎樣定義一個變…

要做PPT,一直找不到資源?

寫于 2016年6月&#xff0c;工作后就很少做PPT了。但工作至今也有人問我如何做PPT有沒有模板之類的問題&#xff08;比如&#xff1a;大學室友做公司年度匯報時也找到我問有沒有模板&#xff0c;我發了這篇文章給他&#xff0c;他說不記得我寫了這篇文章呀&#xff09;&#xf…

Linux系統安裝Appach 2.4.6

轉載鏈接&#xff1a;http://www.cnblogs.com/kerrycode/p/3261101.html Apache簡介 Apache HTTP Server&#xff08;簡稱Apache&#xff09;是Apache軟件基金會的一個開放源碼的網頁服務器&#xff0c;可以在大多數計算機操作系統中運行&#xff0c;由于其多平臺和安全性被廣…

[網摘].NET 程序員十種必備工具-概述

從 MSDN 中看到這篇文章&#xff0c;覺得不錯轉了過來&#xff0c;對于我這樣的.NET新手來說每個工具都是提高效率的好開始。將這十款軟件的介紹重新格式化一下&#xff0c;方便以后查閱。以 “.NET 程序員十種必備工具”開頭的10篇文章都是從這篇文章中分離出來&#xff0c;每…

完整asp.net圖形驗證碼程序

1、測試頁面&#xff1a;Default.aspx <% Page Language"C#" AutoEventWireup"true" CodeFile"Default.aspx.cs" Inherits"_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &q…

學習 redux 源碼整體架構,深入理解 redux 及其中間件原理

如果覺得內容不錯&#xff0c;可以設為星標置頂我的公眾號1. 前言你好&#xff0c;我是若川。這是學習源碼整體架構系列第八篇。整體架構這詞語好像有點大&#xff0c;姑且就算是源碼整體結構吧&#xff0c;主要就是學習是代碼整體結構&#xff0c;不深究其他不是主線的具體函數…

pdf安裝包_有么有pdf控件,不需要用戶安裝任何安裝包直接打印的?

如果開發一個軟件&#xff0c;需要用到PDF功能&#xff0c;您的選擇是基于Adobe PDF嗎&#xff1f; 如果是基于Adobe PDF&#xff0c;需要用戶安裝一個幾十M的Adobe的安裝包&#xff0c;這顯然是不友好的。即使目前也有了一些其它的閱讀器&#xff0c;大小也還好。但是&#xf…

Centos編譯安裝Apache 2.4.6筆記 配置

轉載鏈接&#xff1a;http://www.onepx.com/centos-apache-246.html 之前服務器 Apache 版本一直是 2.2.x&#xff0c;鑒于 Centos 更新軟件的惰性&#xff0c;我看直到 2014 年結束&#xff0c;apache 2.4 都不一定會出現在 Centos 中&#xff0c;我是不打算等了&#xff0c;…

[轉] C#異步操作

Title 通過委托實現異步調用中BeginInvoke及回調函數的使用 通過委托實現異步調用的步驟&#xff1a; 1.定義委托。 2.將要進行異步調用的方法“實例化”到定義的委托。 3.在委托上調用BeginInvoke方法。其中&#xff0c;BeginInvoke的參數由三個部分構成。第一部分&#xff1…

HTTP Server Error 500 內部服務器錯誤

問題&#xff1a;HTTP500錯誤 或 Server Application Error ------------------------------------Server Application ErrorThe server has encountered an error while loading an application during the processing of your request. Please refer to the event log for mo…

使用 ohmyzsh 打造 windows、ubuntu、mac 系統高效終端命令行工具

如果覺得內容不錯&#xff0c;可以設為星標置頂我的公眾號原標題名&#xff1a;oh my zsh 和 windows git bash 設置別名提高效率寫于2018年06月03日在我的微信交流群中聽聞很多前端開發比較貧窮&#xff0c;沒有買mac電腦&#xff08;比如我&#xff09;&#xff0c;也沒有用過…

request獲取mac地址_【Go】獲取用戶真實的ip地址

原文鏈接&#xff1a;https://blog.thinkeridea.com/201903/go/get_client_ip.html用戶請求到達提供服務的服務器中間有很多的環節&#xff0c;導致服務獲取用戶真實的 ip 非常困難&#xff0c;大多數的框架及工具庫都會封裝各種獲取用戶真實 ip 的方法&#xff0c;在 exnet 包…

Installation of Apache HTTPD

轉載鏈接&#xff1a;http://www.linuxfromscratch.org/blfs/view/svn/server/apache.html Installation of Apache-2.4.7 HTTPD For security reasons, running the server as an unprivileged user and group is strongly encouraged. Create the following group and user…

iPhone開發四劍客之《Objective-C基礎教程》

iPhone 開發四劍客之《Objective-C 基礎教程》 Objective-C 語言是 C 語言的一個擴展集&#xff0c;許多&#xff08;可能是大多數&#xff09;具備 Mac OS X 外觀的應用程序都是使用該語言開發的。它以 C 語言為基礎&#xff0c;添加了一些微妙但意義重大的特性。 蘋果公司為…

教師節,你記憶中老師說過印象最深的是什么話?(抽獎)

我記憶中老師說過印象最深的話小學老師&#xff1a;1、小學語文老師李老師說&#xff0c;以后你們可能帶個手機就可以支付了~不需要帶現金。&#xff08;在杭州確實實現了&#xff0c;用支付寶即可&#xff09; 2、小學數學老師李老師說&#xff1a;好好讀書的目的是啥&#xf…

Spark List組件滾動條加事件使datalist數據發生變化

<?xml version"1.0" encoding"utf-8"?><!-- http://blog.flexexamples.com/2009/05/31/detecting-when-the-vertical-scroll-bar-is-scrolled-on-a-spark-list-control-in-flex-4/ --><s:Application name"Spark_List_scroller_vert…

keras訓練完以后怎么預測_還在使用“龜速”的單顯卡訓練模型?動動手,讓TPU節省你的時間...

點擊上方關注&#xff0c;All in AI中國本文將介紹如何使用Keras和Google CoLaboratory與TPU一起訓練LSTM模型&#xff0c;與本地計算機上的GPU相比&#xff0c;這樣訓練能大大縮短訓練時間。很長一段時間以來&#xff0c;我都在單張GTX 1070顯卡上訓練我的模型&#xff0c;它的…