摘要:這個屬性本身又是一個類型的對象,原型對象都包含一個指向構造函數的指針,而每一個實例也都包含一個指向原型對象內部的指針。
前陣子忙于準備CET-6,沒時間更新文章,之后大概一個月將忙于準備期末考,也應該不會更新了,今天趁周末有時間再更新一篇最近研究的一些東西吧。
callee和callerfunction inner(){ console.log(arguments.callee);//指向擁有這個arguments對象的函數,即inner() console.log(arguments.callee.caller);//這個屬性保存著調用當前函數的函數的引用,即outer() console.log(inner.caller);//[Function: outer] } function outer(){ inner(); } outer();
callee放回正在執行的函數本身的引用,它是arguments的一個屬性
caller 返回一個函數的引用,這個函數調用了當前的函數。
嚴格模式下,不允許訪問arguments.callee和arguments.caller屬性,主要體現在arguments.[[Get]]內部方法
嚴格模式下,arguments,arguments.callee,arguments.caller,arguments.callee.caller也不允許再被賦值。如下代碼所示:
"use strict"; // 兩次都是1 void function fn(a) { console.log(arguments[0]); a = 2; console.log(arguments[0]); }(1); //function(){}(); 會運行錯誤, 如下可以正確被運行. void function(){ console.log("hi");//hi }();
在使用立即執行的函數表達式時,可以利用 void 運算符讓 JavaScript 引擎把一個函數識別成函數表達式而不是函數聲明(語句)。
實參和形參var add = function (a,b) { console.log(arguments.length);//3,表示實參長度 console.log(arguments.callee.length);//2,表示形參長度 }; add(1,2,3);Array.prototype.slice.call(arguments)
slice有兩個用法,一個是String.slice,一個是Array.slice,第一個返回的是字符串,第二個返回的是數組。
Array.prototype.slice.call(arguments)能夠將arguments轉成數組,那么就是arguments.toArray().slice();
因為arguments并不是真正的數組對象,只是與數組類似而已,所以它并沒有slice這個方法,而Array.prototype.slice.call(arguments)可以理解成是將arguments轉換成一個數組對象,讓arguments具有slice()方法。 比如:
var arr = [1,2,3,4]; console.log(Array.prototype.slice.call(arr,2));//[3,4]
同樣,還有Array.prototype.forEach.call(),forEach() 方法讓數組的每一項都執行一次給定的函數。
String()我們可以用String()來確定某一變量是否是null或者undefined
var a , b = null; String(a);//undefined String(b);//null
直接調用String()作為方法時,將會執行類型轉換,返回經過toString(value)得到的字符串字面量(與new String()不同),或者空字符串("").
window 對象打開控制臺,你可以看到window對象的一系列屬性和方法:
new functionvar a = function () {}; console.log(typeof a);//function var b = new function () {}; console.log(typeof b);//object var c = new Function (); console.log(typeof c);//function
new function 是一個JavaScript中用戶自定義的對象
var obj = function (name) { this.name = name; }; var b = new obj("trigkit4"); console.log(b.name);js中的false和true
//false console.log(Boolean(""));//false console.log(Boolean(null));//false console.log(Boolean(undefined));//false console.log(Boolean(0));//false console.log(Boolean(false));//false console.log(Boolean(NaN));//false //true console.log(Boolean(" "));//true console.log(Boolean("NaN"));//true
除了false,null,undefined,空字符串"",數字0和NaN以外,其他所有值都被當做是真,包括true,字符串""里包含的值,以及所有對象。
valueOf() 和 toString()valueOf()和toString()方法是所有ECMAScript對象擁有的內置方法。操作對象時,valueOf()和toString()會被隱式的調用。
//valueOf() console.log(Object.valueOf());//[Function: Object] console.log(Object.prototype.valueOf());//{} var boo = new Boolean(1); console.log(boo.valueOf());//true var bar = Boolean(0); console.log(bar.valueOf());//false var str = String("trigkit4"); console.log(str.valueOf());//trigkit4 console.log(null.valueOf());//TypeError console.log(undefined.valueOf());//TypeError //toString() console.log(Object.prototype.toString());//[object Object] console.log(Object.toString());//function Object() { [native code] } Object.prototype.toString.call(null);//[object Null] Object.prototype.toString.call(undefined);//[object Undefined] {a: "b"}.toString();//[object Object]
valueOf()方法的目的是將對象轉換成最有意義的原始值([[PrimitiveValue]])。即ECMAScript的5種基本類型中的三種,布爾值、數字、字符串。
當valueOf方法被調用時,會調用內置的ToObject,并將this作為參數傳進去。ToObject檢測會根據參數類型進行數值的轉換:
Undefined - 拋出TypeError異常 Null - 拋出TypeError異常 Boolean - 創建一個Boolean對象,調用ToBoolean生成[[PrimitiveValue]] Number - 創建一個Number對象,調用ToNumber生成[[PrimitiveValue]] String - 創建一個String對象,調用ToString生成[[PrimitiveValue]] Object - 對象本身
ECMAScript對象的大多數操作的轉換結果是字符串,這兩個方法的結果是相同的。但是如果操作的對象為Number、Boolean或者Date,結果就不同了。
var foo = { toString: function () { return "foo"; }, valueOf: function () { return 5; } }; console.log(foo + "bar"); // 5bar console.log([foo, "bar"].join("")); // foobar
在這個上下文環境中,我們使用"+"操作符來使字符串連接,但是,foo并沒有使用toString來轉換成字符串,它使用valueOf轉換成一個number,這并不是我們想要的,
但它是如何工作的,這是+運算符的算術和字符串連接超載的副作用。"+"操作符有一個明確的處理過程:
1.評估左手側,并得到該值。 2.評估右手側,并獲得該值。 3.同時在左手和右手側調用ToPrimitive(無提示) 4.如果任何原始值是一個字符串,然后跳到7。 5.在這兩個值調用ToNumber。 6.返回值的總和。 7.在這兩個值調用toString。 8.返回的值連接起來setInterval和setTimeout
alert(1); setTimeout("alert(2)", 0); alert(3);
執行順序為:1,3,2,雖然延時了0ms
setTimeout 0 //正常情況下javascript都是按照順序執行的。但是我們可能讓該語句 后面的語句執行完再執行本身,這時就可以用到setTimeout延時0ms來實現了。cookie的創建和刪除
cookie可以跨越一個域名下的多個網頁,但不能跨越多個域名使用。
document.cookie = “user = 值;expires = 過期時間;path = 路徑訪問; domain = 域名訪問;secure = 安全的https限制通信"cookie的創建方式
設置cookie我們一般都封裝成一個函數:
function addCookie(sName,sValue,day) { var expireDate = new Date(); expireDate.setDate(expireDate.getDate()+day);; //設置失效時間 document.cookie = escape(sName) + "=" + escape(sValue) +"; expires=" + expireDate.toGMTString();6 //escape()漢字轉成unicode編碼,toGMTString() 把日期對象轉成字符串 }刪除cookie
為了刪除一個cookie,可以將其過期時間設定為一個過去的時間,例如:
//獲取當前時間 var date=new Date(); //將date設置為過去的時間 date.setTime(date.getTime()-10000); //將userId這個cookie刪除 document.cookie="userId=828; expires="+date.toGMTString();給cookie設置終止日期
到現在為止,所有的cookie都是單會話cookie,即瀏覽器關閉后這些cookie將會丟失,事實上這些cookie僅僅是存儲在內存中,而沒有建立相應的硬盤文件。
在實際開發中,cookie常常需要長期保存,例如保存用戶登錄的狀態。這可以用下面的選項來實現:
document.cookie="userId=828; expiress=GMT_String";
其中GMT_String是以GMT格式表示的時間字符串,這條語句就是將userId這個cookie設置為GMT_String表示的過期時間,超過這個時間,cookie將消失,不可訪問。例如:如果要將cookie設置為10天后過期,可以這樣實現:
對象和函數可以如數組一樣,用屬性名或方法名作為下標來訪問:
對象的創建//對象的創建 function MyFunc(){} var obj1 = new MyFunc();//使用new操作符,借助MyFun函數,就創建了一個對象 var obj2 = new MyFunc;//函數也可以沒有括號,但仍將調用該函數
可以把上面的代碼改寫成這種等價形式:
function MyFunc(){}; var obj1 = {};//創建一個對象 MyFunc.call(obj1);//將obj1對象作為this指針調用MyFunc函數作用域
通過自執行的匿名函數你可以把所有原本屬于全局的變量都隱藏起來:
//創建一個新的匿名函數,作為包裝 (function () { //變量原本應該是全局的 var msg = "Thanks for visiting"; window.onunload = function () { console.log(msg); }; })();
上下文對象是通過this變量體現的,這個變量永遠指向當前代碼所處的對象中。
var obj = { yes : function(){ //this == obj this.val = true; }, no : function(){ this.val = false; } }; console.log(obj.val == null);//true //執行了yes函數后,將val屬性與"obj"對象關聯起來 obj.yes(); console.log(obj.val == true);//trueString 原型方法的擴展
//公共正則表達式處理函數 String.prototype.Regular = function(reg){ var result = true; if(this.length > 0){ if(!reg.test(this)){ result = false; } } return result; } //.trim()方法 String.prototype.trim = function () { return this.replace(/(^s*)|(s*$)/g,""); };
^表示字符串必須以后面的規則開頭,而(^s*) 表示的就是以0個空格或者多個空格開頭,后面的(s*$) 的意思就是, 以0個空格或者多個空格結尾。
//判斷輸入內容是否為空 String.prototype.isNull = function(){ return this.trim().length == 0 ? true : false; } //判斷輸入的字符是否為英文字母數字下劃線 String.prototype.isVersion = function(){ var reg = /^([a-zA-Z_])([a-zA-Z0-9_.])*$/; return this.Regular(reg); } // 判斷輸入的字符串,不包括單引號 String.prototype.isString = function(){ var reg = /^[^"]*$/; return this.Regular(reg); } //判斷輸入的字符是否為英文字母 String.prototype.isLetter = function(){ var reg = /^[a-zA-Z]+$/; return this.Regular(reg); }constructor屬性
function User(){} var me = new User(); console.log(me.constructor);//[Function: User] //用前一個對象的Constructor引用來創建一個新的User對象 var you = new me.constructor(); console.log(me.constructor == you.constructor);//trueObject.create
function Parent(){} var o = Object.create(Parent.prototype); console.log(o instanceof Parent);//true console.log(o instanceof Object);//true console.log(Object.prototype.toString.call(o));//[object Object]
“數據屬性”是可獲取且可設置值的屬性。 數據屬性描述符包含 value 特性,以及 writable、enumerable 和 configurable 特性。 如果未指定最后三個特性,則它們默認為 false。
function Parent(){} var o = Object.create(Parent); console.log(o instanceof Parent);//false console.log(o instanceof Object);//true
另外一個實例
var book1 = { title:"JS高級程序設計", pages : 1001, getTitle:function(){ console.log(this.title); } }; var book2 = Object.create(book1,{ //title會成為所創建對象的數據屬性 title:{ configurable:true, enumerable:true, value:"JS權威指南", wratable:true } }); book1.getTitle(); //"JS高級程序設計" book2.getTitle(); //"JS權威指南" console.log(book1.hasOwnProperty("getTitle")); //true console.log("pages" in book2); //true console.log(book2.hasOwnProperty("getTitle")); //false console.log(book1.isPrototypeOf(book2));//true
再看另一個例子:
function Constructor(){} obj = new Constructor(); // 上面的一句就相當于: obj = Object.create(Constructor.prototype); console.log(obj);//{} console.log(Object.create(Constructor.prototype));//{} console.log(obj instanceof Constructor);//true console.log(Constructor.prototype.isPrototypeOf(obj));//true var foo; foo = {}; // 以字面量方式創建的空對象就相當于: foo = Object.create(Object.prototype);
另外:
console.log(Object.prototype);//{} console.log(Object.create(Object.prototype));//{}
通過Object.create(Object.prototype) 創建的實例對象就繼承了Object原型下的屬性和方法。
javascript所有function類型的對象都有一個prototype屬性。這個prototype屬性本身又是一個object類型的對象,原型對象都包含一個指向構造函數的指針,而每一個實例也都包含一個指向原型對象內部的指針。
參考:https://developer.mozilla.org...prototype
function User(){} var u1 = new User(); console.log(u1.prototype);//使用對象實例無法訪問到prototype console.log(User.prototype);//{},使用構造函數名訪問prototype console.log(u1.__proto__);//{},使用對象實例訪問prototype的指針 //使用字面量的方式創建原型對象,這里{}就是對象 User.prototype = { name : "trigkit4", age : 22 };
使用構造函數創建原型對象和使用字面量創建對象在使用上基本相同,但還是有些區別,字面量創建的方式使用constructor屬性不會指向實例,而會指向Object,構造函數創建的方式則相反
function User(){} User.prototype = { name : "trigkit4", age : 22 }; var u1 = new User(); console.log(u1.constructor);//function Object() {[native code]} console.log(u1 instanceof User);//true console.log(u1.constructor == User);//false console.log(u1.constructor == Object);//true //如果想讓字面量方式的constructor指向實例對象,可以這么做: User.prototype = { constructor : User; }
字面量方式為什么constructor會指向Object?因為User.prototype = {};這種寫法其實就是創建了一個新對象:
function User(){} User.prototype = { constructor : User }; var u1 = new User(); console.log(User.constructor);//[Function: Function] console.log(u1.constructor == User);//true
另一個例子:
(function () { console.log(Object.prototype);//{} console.log(Array.prototype);//[] console.log(Array.prototype.push);//[Function: push] console.log(Function.prototype);//[Function: Empty] console.log(Function.prototype.bind);//[Function: bind] })();Object.prototype.toString
在toString()方法被調用時,會執行下面的操作步驟:
如果this的值為undefined,則返回"[object Undefined]". 如果this的值為null,則返回"[object Null]". 讓O成為調用ToObject(this)的結果. 讓class成為O的內部屬性[[Class]]的值. 返回三個字符串"[object ", class, 以及 "]"連接后的新字符串.
由于 JavaScript 中一切都是對象,任何都不例外,對所有值類型應用Object.prototype.toString.call()
方法結果如下:
console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toString.call("123")) //[object String] console.log(Object.prototype.toString.call(undefined)) //[object Undefined] console.log(Object.prototype.toString.call(true)) //[object Boolean] console.log(Object.prototype.toString.call({})) //[object Object] console.log(Object.prototype.toString.call([])) //[object Array] console.log(Object.prototype.toString.call(function(){})) //[object Function]
?
所有類型都會得到不同的字符串,幾乎完美。
在JavaScript中,想要判斷某個對象值屬于哪種內置類型,最靠譜的做法就是通過Object.prototype.toString方法.
下面是來自Prototype.js的一段代碼:
//創建一個名為"Class"的全局對象 var Class = { //它只有一個函數,其作用是創建一個新的對象構造函數 create: function(){ //創建一個匿名的對象構造函數 return function () { //調用它本身的初始化方法 this.initialize.apply(this,arguments); } } }; //給Object對象添加一個新的靜態方法,它的作用是把屬性從一個對象復制到另一個中 Object.extend = function (destination,source) { //遍歷所有要擴展的屬性 for(property in source){ //然后將他們添加到目標對象中 destination[property] = source[property]; } };成員操作符
function aFunc(){}//或者var aFunc = function(){}; aFunc.oProperty = "函數的一個屬性"; aFunc.aMethod = function(){ console.log("函數的一個方法"); }; console.log(aFunc["oProperty"]);//將函數當成數組以屬性名作為下標來訪問屬性 console.log(aFunc["aMethod"]());//將函數當數組以方法名作為下標來調用方法 //遍歷函數的所有屬性和方法 for(var s in aFunc){ console.log(s + "is a "+typeof(aFunc[s])); }特權方法與私有方法
function Constructor(msg){ this.Message = msg; //私有屬性 var separator = "-"; var owner = this; //私有方法 function alertMessage(){ console.log(owner.Message); } alertMessage(); //特權方法(也是公有方法) this.aptMessage = function (str) { this.Message += separator + str; alertMessage(); } } //公有方法 Constructor.prototype.clearMessage = function (str) { this.Message = ""; }; //靜態屬性 Constructor.name = "trigkit4"; //靜態方法 Constructor.alertName = function (name) { console.log(this.name); };
特權方法是指在構造函數的作用域中使用this關鍵字定義的方法;與私有方法不同,特權方法能夠被公開訪問,而且還能夠訪問私有成員。
由于私有和特權成員在函數的內部,因此它們會被帶到函數的每個實例中。
公有的原型成員是對象藍圖的一部分,適用于通過new關鍵字實例化的該對象的每個實例 靜態成員只適用于對象的一個特殊實例
使用對象字面量語法來向prototype屬性添加所有公有成員:
function Constructor(){ //私有和特權成員 } //公有方法 Constructor.prototype = { propertyA: "value1", propertyB: "value2", methodA: function(){}, methodB: function(){} };刪除不要的節點
DOM 元素在瀏覽器中所占用的空間是非常大的,要及時回收不用的節點:
var node = parentNode.removeChild(node); node = null;//設置為空,釋放空間 CollectGarbage();//IE,回收資源
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85743.html
摘要:的作用相當于,將其轉換為布爾值。用于判斷一個變量是否某個對象的實例,如返回同時也會返回返回布爾值,如果為,則返回,否則返回的結果。 underscore.js源碼 Underscore.js 沒有對原生 JavaScript 對象進行擴展,而是通過調用 _() 方法進行封裝,一旦封裝完成,原生 JavaScript 對象便成為一個 Underscore 對象。 判斷給定變量是否是對象 ...
摘要:在考慮宇航員的生命安全時,輕微的打嗝或者服務中斷都會釀成生死事故。也許最大的挑戰來自谷歌主導的簡稱。在最近的開發者峰會,以及今年的會議上,谷歌都為安排了大量討論。由微軟提供,是廣受歡迎的編輯器,到月份已經獲得了超過五百萬用戶。 譯者:安冬 (滬江Web前端開發工程師)本文原創翻譯,轉載請注明作者及出處。原文地址:http://developer.telerik.com/... 技術世界...
摘要:基于原生主要是針對基于比較來說的,基于的我不想再討論了,我想嘗試的是從到功能都是原生,而不是用模擬的所謂原生體驗。 基于原生主要是針對基于webview+h5比較來說的,基于H5的我不想再討論了,我想嘗試的是從UI到功能都是原生,而不是用H5模擬的所謂原生體驗。 背景 我們從開發角度來考慮,但凡想從事長遠的開發工作,都有自己的技術積累,最簡單的就是一些UI組件和功能組件的封裝。 舉例,...
摘要:基于原生主要是針對基于比較來說的,基于的我不想再討論了,我想嘗試的是從到功能都是原生,而不是用模擬的所謂原生體驗。 基于原生主要是針對基于webview+h5比較來說的,基于H5的我不想再討論了,我想嘗試的是從UI到功能都是原生,而不是用H5模擬的所謂原生體驗。 背景 我們從開發角度來考慮,但凡想從事長遠的開發工作,都有自己的技術積累,最簡單的就是一些UI組件和功能組件的封裝。 舉例,...
摘要:忍者級別的函數操作對于什么是匿名函數,這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數是一個很重要且具有邏輯性的特性。通常,匿名函數的使用情況是創建一個供以后使用的函數。 JS 中的遞歸 遞歸, 遞歸基礎, 斐波那契數列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執行機制 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果...
閱讀 2574·2021-09-30 09:48
閱讀 2564·2019-08-30 14:10
閱讀 2708·2019-08-29 11:22
閱讀 1837·2019-08-26 13:51
閱讀 2276·2019-08-26 12:02
閱讀 2415·2019-08-23 16:06
閱讀 3548·2019-08-23 14:06
閱讀 1093·2019-08-23 13:56