Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
avaScript中的數(shù)據(jù)類型檢測是一個重要的概念,它涉及到如何確定一個變量或者值的類型。在JavaScript中,有多種方法可以用來檢測數(shù)據(jù)類型,包括typeof、instanceof、Object.prototype.toString、Array.isArray和NaN判斷等。下面將詳細介紹這些數(shù)據(jù)類型檢測方案:
綜上所述,JavaScript提供了多種數(shù)據(jù)類型檢測方案,每種方案都有其用途和限制。在實際開發(fā)中,應(yīng)根據(jù)具體需求選擇合適的方法來確保數(shù)據(jù)類型的正確判斷。
JavaScript中,有多種方法可以判斷一個變量的數(shù)據(jù)類型。以下是一些常見的方法:
typeof 是JavaScript中的一元操作符,返回一個表示未計算變量類型或已計算對象類型的字符串。但是,需要注意的是 typeof 對于 null 和 array 的處理可能不是你所期望的:
console.log(typeof undefined); // "undefined"
console.log(typeof 123); // "number"
console.log(typeof 'hello'); // "string"
console.log(typeof true); // "boolean"
console.log(typeof {}); // "object"
console.log(typeof []); // "object" 而不是 "array"
console.log(typeof null); // "object" 而不是 "null"
console.log(typeof function(){}); // "function"
instanceof 操作符用于檢測構(gòu)造函數(shù)的 prototype 屬性是否出現(xiàn)在對象的原型鏈中的任何位置。這主要用于檢測對象是否屬于某個類。
console.log([] instanceof Array); // true
console.log(null instanceof Object); // false,因為 null 不是一個對象
這是檢測一個值是否為數(shù)組的最佳方法。
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
這個方法返回表示該對象的字符串。對于檢測原始值類型,特別是當(dāng) typeof 給出不直觀的結(jié)果時(如 null 和 array),這是一個很有用的方法。
function getType(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
console.log(getType(null)); // "Null"
console.log(getType([])); // "Array"
console.log(getType({})); // "Object"
console.log(getType(123)); // "Number"
console.log(getType('hello')); // "String"
console.log(getType(true)); // "Boolean"
console.log(getType(undefined)); // "Undefined"
每個JavaScript對象都有一個 constructor 屬性,它指向創(chuàng)建該對象的構(gòu)造函數(shù)。但請注意,如果 constructor 被手動修改,則可能不準(zhǔn)確。
console.log(([]).constructor===Array); // true
console.log(({}).constructor===Object); // true
某些內(nèi)置對象(如 Array、Date、RegExp 等)的 @@toStringTag 屬性值是一個字符串,該字符串用于定制 Object.prototype.toString.call(obj) 的默認行為。但通常你不需要直接使用這個屬性,除非你在實現(xiàn)自定義對象并希望改變 Object.prototype.toString.call(obj) 的默認行為。
在 javascript 中,判斷一個變量的類型可以用 typeof
在 javascript 中,instanceof 用于判斷某個對象是否被另一個函數(shù)構(gòu)造使用 typeof 運算符時采用引用類型存儲值會出現(xiàn)一個問題,無論引用的是什么類型的對象,它都返回”object”。ECMAScript 引入了另一個 Java 運算符 instanceof 來解決這個問題。
Instanceof 運算符與 typeof 運算符相似,用于識別正在處理的對象的類型。與 typeof 方法不同的是,instanceof 方法要求開發(fā)者明確地確認對象為某特定類型
typeof 只能區(qū)分值類型
typeof undefined // undefined
typeof null // object
typeof console.log // function
typeof NaN // number
軟件模塊之間總是存在著一定的接口,從調(diào)用方式上,可以把他們分為三類:同步調(diào)用 、回調(diào) 和 異步調(diào)用
同步調(diào)用 是一種阻塞式調(diào)用,調(diào)用方要等待對方執(zhí)行完畢才 返回,它是一種單向調(diào)用;
回調(diào) 是一種雙向調(diào)用模式,也就是說,被調(diào)用方在接口被調(diào)用時也會調(diào)用對方的接口;
異步調(diào)用 是一種類似消息或事件的機制,不過它的 調(diào)用方向剛好相反,接口的服務(wù)在收到某種訊息或發(fā)生某種事件時,會主動通知客戶方(即調(diào)用客戶方的接口)。回調(diào)和異步調(diào)用的關(guān)系非常緊密,通常我們使用回 調(diào)來實現(xiàn)異步消息的注冊,通過異步調(diào)用來實現(xiàn)消息的通知。同步調(diào)用是三者當(dāng)中最簡單的,而回調(diào)又常常是異步調(diào)用的基礎(chǔ),因此,下面我們著重討論回調(diào)機制在不同軟件架構(gòu)中的實現(xiàn)
回調(diào)函數(shù) 就是一個通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),當(dāng)這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)?;卣{(diào)函數(shù)不是由該函數(shù)的實現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時由另外的一方調(diào)用的,用于對該事件或條件進行響應(yīng)
案例:
#include<stdio.h>
//callbackTest.c
//1.定義函數(shù) onHeight(回調(diào)函數(shù))
//@onHeight 函數(shù)名
//@height 參數(shù)
//@contex 上下文
void onHeight(double height, void *contex)
{
printf("current height is %lf", height);
}
//2.定義 onHeight 函數(shù)的原型
//@CallbackFun 指向函數(shù)的指針類型
//@height 回調(diào)參數(shù),當(dāng)有多個參數(shù)時,可以定義一個結(jié)構(gòu)體
//@contex 回調(diào)上下文,在 C 中一般傳入 nullptr,在 C++中可傳入對象指針
typedef void (*CallbackFun)(double height, void *contex);
//定義全局指針變量
CallbackFun m_pCallback;
//定義注冊回調(diào)函數(shù)
void registHeightCallback(CallbackFun callback, void *contex)
{
m_pCallback=callback;
}
//定義調(diào)用函數(shù)
void printHeightFun(double height)
{
m_pCallback(height, NULL);
}
//main 函數(shù)
int main()
{
//注冊回調(diào)函數(shù) onHeight
registHeightCallback(onHeight, NULL);
//打印 height
double h=99;
printHeightFun(99);
}
“閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。例如在 javascript 中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,所以閉包可以理解成“定義在一個函數(shù)內(nèi)部的函數(shù)“。在本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部連接起來的橋梁?!?/span>
舉例:創(chuàng)建閉包最常見方式,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)。下面例子中的 closure 就是一個閉包
function func(){
var a=1 ,b=2;
funciton closure(){
return a + b;
}
return closure;
}
內(nèi)存泄漏指任何對象在您不再擁有或需要它之后仍然存在
function foo(arg) {
bar='some text'; // 等同于 window.bar='some text';
}
function foo() {
this.var1='potential accident'
}
在 JavaScript 中使用 setInterval 非常常見
大多數(shù)庫都會提供觀察者或者其它工具來處理回調(diào)函數(shù),在他們自己的實例變?yōu)椴豢蛇_時,會讓回調(diào)函數(shù)也變?yōu)椴豢蛇_的。對于 setInterval,下面這樣的代碼是非常常見的:
var serverData=loadData();
setInterval(function() {
var renderer=document.getElementById('renderer');
if(renderer) {
renderer.innerHTML=JSON.stringify(serverData);
}
}, 5000); //This will be executed every ~5 seconds.
這個例子闡述著timers 可能發(fā)生的情況:計時器會引用不再需要的節(jié)點或數(shù)據(jù)
JavaScript 開發(fā)的一個關(guān)鍵方面就是閉包:一個可以訪問外部(封閉)函數(shù)變量的內(nèi)部函數(shù)。由于 JavaScript 運行時的實現(xiàn)細節(jié),可以通過以下方式泄漏內(nèi)存:
var theThing=null;
var replaceThing=function () {
var originalThing=theThing;
var unused=function () {
if (originalThing) // a reference to 'originalThing'
console.log("hi");
};
theThing={
longStr: new Array(1000000).join('*'),
someMethod: function () {
console.log("message");
}
};
};
setInterval(replaceThing, 1000);
有時候,在數(shù)據(jù)結(jié)構(gòu)中存儲 DOM 結(jié)構(gòu)是有用的。假設(shè)要快速更新表中的幾行內(nèi)容。將每行DOM 的引用存儲在字典或數(shù)組中可能是有意義的。當(dāng)這種情況發(fā)生時,就會保留同一 DOM 元素的兩份引用:一個在 DOM 樹種,另一個在字典中。如果將來某個時候你決定要刪除這些行,則需要讓兩個引用都不可達。
var elements={
button: document.getElementById('button'),
image: document.getElementById('image')
};
function doStuff() {
elements.image.src='http://example.com/image_name.png';
}
function removeImage() {
// The image is a direct child of the body element.
document.body.removeChild(document.getElementById('image'));
// At this point, we still have a reference to #button in the
//global elements object. In other words, the button element is
//still in memory and cannot be collected by the GC.
}
JavaScript 是一種通過原型實現(xiàn)繼承的語言與別的高級語言是有區(qū)別的,像 java,C#是通過類型決定繼承關(guān)系的,JavaScript 是的動態(tài)的弱類型語言,總之可以認為 JavaScript 中所有都是對象,在 JavaScript 中,原型也是一個對象,通過原型可以實現(xiàn)對象的屬性繼承,JavaScript 的對象中都包含了一個” prototype”內(nèi)部屬性,這個屬性所對應(yīng)的就是該對象的原型
“prototype”作為對象的內(nèi)部屬性,是不能被直接訪問的。所以為了方便查看一個對象的原型,Firefox 和 Chrome 內(nèi)核的 JavaScript 引擎中提供了”proto“這個非標(biāo)準(zhǔn)的訪問器(ECMA 新標(biāo)準(zhǔn)中引入了標(biāo)準(zhǔn)對象原型訪問器”Object.getPrototype(object)”)
原型的主要作用就是為了實現(xiàn)繼承與擴展對象
JavaScript 原型: 每個對象都會在其內(nèi)部初始化一個屬性,就是 prototype(原型)
原型鏈:當(dāng)我們訪問一個對象的屬性時,如果這個對象內(nèi)部不存在這個屬性,那么他就會去 prototype 里找這個屬性,這個 prototype 又會有自己的 prototype,于是就這樣一直找 下去,也就是我們平時所說的原型鏈的概念
特點:JavaScript 對象是通過引用來傳遞的,我們創(chuàng)建的每個新對象實體中并沒有一份屬于自己的原型副本。當(dāng)我們修改原型時,與之相關(guān)的對象也會繼承這一改變
繼承有以下六種方法:
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。