有好多好多的函式跟閉包在這裡!進階用法要注意上下文綁定的內容,還可以使用 prototype 功能,去增加函式的使用行為。但進階用法需要更小心使用。
每個透過閉包存取資訊的函式,都有條「鎖腳鏈」,拖著資訊、附加在函式上,所以閉包極為有用,但並非不會造成負擔與花費,上述那些資訊都會佔用記憶體,直到 JavaScript 執行引擎確定不再需要(也就是能夠被當成垃圾、被系統回收),或是直到頁面消失。
function Account() {
var deposit = 0;
this.save = function () {
deposit++;
}
this.take = function () {
deposit > 0 ? deposit-- : 0
}
this.getTotal = function () {
return deposit;
}
}
var myAccount = new Account()
myAccount.save()
myAccount.getTotal() //1
myAccount.take()
myAccount.getTotal() //0
fetch('https://jsonplaceholder.typicode.com/todos/10')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
return function(){
return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)))
}
}
var myObject = {};
function myFunction(){
return this == myObject;
}
aFunction = myFunction.bind(myObject)
var elements1 = "val1,val2,val3".split(/,\s*/);
var elements2 = "val1,val2,val3".split(/,\s*/);
var elements3 = "val1, val2, val3".split(/,\s*/);
//\s為空白 * 為0~多個,意思指逗點加空白為切割字串方式,所以 1 ,2 ,3 會得到相同結果,擷取出的字串不包含空白字元
Function.prototype.partial = function() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function(){
var arg = 0;
for (var i = 0; i < args.length && arg < arguments.length; i++) {
if(args[i] === undefined) {
args[i] = arguments[arg++]
}
}
return fn.apply(this, args);
}
}
var delay = setTimeout.partial(undefined, 3000);
delay(function(){
console.log("3 sec later")
})
Function.prototype.memoized = function(key){
this._values = this._values || {};
return this._values[key] !== undefined ? this._values[key] : this._values[key] = this.apply(this, arguments);
}
Function.prototype.memoize = function(){
var fn = this;
return function(){
return fn.memoized.apply(fn, arguments);
}
}
var isPrime = (function(num) {
var prime = num != 1;
for (var i = 2; i < num; i++) {
if(num % i == 0) {
prime = false;
break;
}
}
return prime;
}).memoize();
console.log(isPrime(12)) //false
console.log(isPrime(2147483647)) //true,會跑超久
console.log(isPrime(2147483647)) //true,不用等
function wrap(object, method, wrapper) {
var fn = object[method];
return object[method] = function() {
return wrapper.apply(this, [fn.bind(this)].concat(Array.prototype.slice.call(arguments)))
}
}
if(Prototype.Browser.Opera) {
wrap(Element.Methods, "readAttribute", function(original, elem, attr) {
return attr == "title" ? elem.title : original(elem, attr)
})
}
//有點像 polyfill,例如想修改 forEach 為倒序
let fruits = ['apple', 'banana', 'peach']
Array.prototype.forEach = function(callback){
for(i=this.length; i > -1; i--){
callback(this[i])
}
}
fruits.forEach(function(element){
console.log(element)
})
//忍者裡的奇怪例子
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++) (function(n){
divs[n].addEventListener("click", function(){
console.log("I am here!")
}, false)
})(i);
https://developer.mozilla.org/zh-TW/docs/Web/API/Fetch_API/Using_Fetch
https://jsonplaceholder.typicode.com/
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/split