2011-07-22 30 views
16

Bir değeri, ilkel veya kutulu olup olmadığını belirlemek için typeof kullanabilirsiniz.Bir değerin ilkel mi yoksa kutulu mu

düşünün: Object.prototype.toString ile birlikte

typeof "foo"; // "string" 
typeof new String("foo"); // "object" 

biz

var toString = Object.prototype.toString; 

var is_primitive_string = function(s) { 
    return toString.call(s) === "[object String]" && typeof s === "string"; 
}; 

var is_boxed_string = function(s) { 
    return toString.call(s) === "[object String]" && typeof s === "object"; 
}; 

herhangi kullanım durumları bu iki fonksiyon için var mıdır aşağıdaki iki işlevi tanımlayabilirsiniz? (Veya Number,, vb için benzer işlevler).

Bu sorunun arkasındaki kavram aşağıdaki Comment by T.J.Crowder'dan geldi.

Sahip olduğumuz bir değerin ilkel mi yoksa kutulu mu olduğunu hiç düşünmemeli miyiz?

cevap

7

Ben derim: isEmpty, izelement, isArray, isArguments, isFunction, isString, ISNUMBER, isBoolean, ısdate, isRegExp isNaN, ISNULL,

burada tarif

isUndefined Bir string ilkel veya String nesnesini ele alıp almadığınıza neredeyse hiç önem vermiyorsunuz.

Kenarlıklar vardır. Örneğin, String nesnesi gerçek bir nesnedir, ona özellik ekleyebilirsiniz. Bu da, bu gibi şeyler yapalım: kodunu arayarak geçirir

function test(arg) { 
    arg.foo = "bar"; 
} 

Bir stringilkel:

var s1 = "str"; 
test(s1); 

... arg bir String nesneye terfi ve mülkiyet buna eklenir alır alır Ancakdöndürdüğünde String nesnesi hiçbir şey tarafından kullanılmaz.

aksine, kod çağıran bir Stringnesne içinde geçerse:

var s2 = new String("str"); 
test(s2); 

... sonra mülkiyet o nesneye eklenir ve arama kodu görebilirsiniz. ( live copy) düşünün:

var s1, s2; 

s1 = "str"; 

display("[Before] typeof s1.foo = " + typeof s1.foo); 
test(s1); 
display("[After] typeof s1.foo = " + typeof s1.foo); 

s2 = new String("str"); 

display("[Before] typeof s2.foo = " + typeof s2.foo); 
test(s2); 
display("[After] typeof s2.foo = " + typeof s2.foo); 

function test(arg) { 
    arg.foo = "bar"; 
} 

Çıktı: s2.foo bir dize olmakla s1 bir dize ilkel çünkü s1.foo (değil

[Before] typeof s1.foo = undefined 
[After] typeof s1.foo = undefined 
[Before] typeof s2.foo = undefined 
[After] typeof s2.foo = string

Not olduğunu, bunu teşvik oluşturulan nesne test numaralı telefonun arama kodu ile ilgisi yoktur).

Bunun için herhangi bir kullanım durumu var mı? Dunno. Eğer öyleyse, son derece sinirli bir kenar durum olacağını söyleyebilirim.

+0

Kutulu değerlerin ilkellere kıyasla "referans olarak geçirilmiş" olması, bazı ilginç sonuçlara neden olabilir. – Raynos

+1

@Raynos, ne sonuçları? Primitifler değişmezdir, bu yüzden ilkel değerler için geçiş değeri ile başvuru kaynağı arasında gözlemlenebilir bir fark olmamalıdır. Tek bir bellek konumunda (Rhino'da olduğu gibi) ve taklit edilmiş bir sendikada bulunan bir değişmez nesnenin bir referansı olarak geçip geçmediğini algılayabilecek herhangi bir program olduğunu düşünmüyorum. çoğu diğer tercümanlarda olduğu gibi kopyalanır. –

3

Tüm toString öğelerinin tümü, farklı yapıdaki String yapıcıların kareli karıĢtırma karĢı karĢı karĢı karĢı karĢı karĢı karĢı karĢı karĢı karĢıya karĢı problemlerle karĢılaĢtırılması gibi görünüyor. Bir şey ilkel bir dize olup olmadığını kontrol etmek için gereksizdir - typeof yeterli, bu nedenle is_primitive_string için kullanım durumu yoktur.

bir şey yerine ("" + s) veya String(s) yoluyla String değere şiddet uygulanması String örneği çerçeveler arası olup olmadığını kontrol etmek gerekir neden göremiyorum bu yüzden çok nadiren String örnekleri olarak geçirilen argümanları görüyoruz. Üretim kodunda String değerini kullandığım tek zamandı, bazı highly optimized code modelinde doğru olan boş bir dizeye ihtiyacım vardı.

Diğerleri gittikçe, Boolean sınıfının durumları, koşullardan beklendiği gibi davranmaz.

if (new Boolean(false)) { 
    alert("WTF!"); 
} else { 
    alert("OK"); 
} 

Boolean.prototype.not = function() { return !this; }; 

if (new Boolean(false).not()) { 
    alert("OK"); 
} else { 
    alert("Really, WTF!"); 
} 

if (false.not()) { // Autoboxing 
    alert("OK"); 
} else { 
    alert("Cmon, WTF!"); 
} 

!(false)true, ancak Boolean sınıfının bir örneğini oluşturmak kullandığınızda, ! operatör nesne değeri için geçerlidir ve nesne değerleri her zaman truthy bulunmaktadır.

Ben ECMAscript 5 katı mod son örneği ( false.not()) "use strict"; geçerli bir ES5 tercüman içinde Boolean.prototype.not üstüne eklendiğinde biri safça tahmin edebileceğiniz gibi davranacaktır böylece this sunulma şeklini değiştiriyor inanıyoruz.

Number s ile < arasındaki karşılaştırmalar tamamdır ve ekleme ve diğer işleçleri beklendiği gibi çalışmaya eğilimlidir. new Number(0) ve new Number(NaN) koşullar etrafında new Boolean(false) aynı sorunlar var ve tabii ki

alert(NaN === NaN); // false 
var NAN = new Number(NaN); 
alert(NAN === NAN); // true 

ve === ve !==String, Number ve Boolean tümü için referans olarak karşılaştırın.

+0

Boolean mantığından ve '!' Operatöründen ayrı olarak. Kutulu ve ilkel türlerde garip davranan başka bir şey var mı? Ve buna karşı bir şey yapmalı mıyız? – Raynos

+0

@Raynos, açıkça 'yeni Sayı (0) 'gerçektir ve' var NAN = yeni Sayı (NaN); uyarısı (NAN === NAN && !! NAN) '. –

-2

Değişken türünü algılamak için underscore.js yöntemlerini kullanırım.kullanmayı deneyin: neredeyse hiçbir anlamı yok http://documentcloud.github.com/underscore/

+1

Türü hakkında konuşmuyoruz, bir değerin belirli bir tür için ilkel veya kutulu tip olup olmadığını kontrol etmekten bahsediyorduk (String, Number, Boolean) – Raynos

+0

Pardon me. Soruyu yanlış anladım. – czerasz

İlgili konular