2013-11-15 2 views
2

примитивных типов данных я не должен добавлять элементы в массив, как это:добавление свойств к другим, чем массив

var b = []; 
b.val_1 = "a"; 
b.val_2 = "b"; 
b.val_3 = "c"; 

Я не могу использовать собственные методы массива и почему не просто объект. Я просто добавляю свойства к массиву, а не к элементам. Я полагаю, это делает их параллельными с свойством length. Хотя попытка сбросить длину (b.length = "a string") получает Uncaught RangeError: Invalid array length.

В любом случае, я все еще могу видеть свойства, которые я указал, как это:

console.log(b); //[val_1: "a", val_2: "b", val_3: "c"] 

я могу получить доступ к нему, используя точечный синтаксис:

console.log(b.val_1); //a 

Если массив это просто объект таким же образом, что строка или число - это объект, почему не может (не то, что я хотел бы). Я прикрепляю к ним свойства с помощью этого синтаксиса:

var num = 1; 
num.prop_1 = "a string"; 

console.log(num); //1 

я не могу получить доступ к его свойства, используя точечный синтаксис

console.log(num.prp); //undefined 

Почему это может быть сделано с массивом, а не с другими типами данных. Для всех случаев я должен использовать {}, и мне понадобится только {}, так почему же у них есть эта способность?

JSBIN

ответ

5

Поскольку массивы рассматриваются как объекты языка, вы можете увидеть это, введя следующую строку кода:

console.log(typeof []) // object 

Но другие типы, как число литералов, строковых литералов NaN .. и т. д. являются примитивными типами и только завернуты в их репрезентацию объектов в определенных контекстах, определенных языком.

Если вы хотите добавить свойства или методы к ряду, как это, то вы можете использовать Number конструктор так:

var num = new Number(1); 
num.prop_1 = "fdadsf"; 
console.log(num.prop_1); 

Использование Number конструктор возвращает объект номер, который вы можете увидеть, набрав следующая строка:

console.log(typeof num); // object 

в то время как в первом случае:

var num = 1; 
console.log(typeof num) // number 

EDIT 2: При вызове метода на ряде буквальным или строка буквального, например, то, что примитив автоматически упаковывается в его объектного представления языком для вызова метода иметь место, например:

var num = 3; 
console.log(num.toFixed(3)); // 3.000 

Здесь num - это примитивная переменная, но когда вы вызываете код toFixed(), она обертывается на объект Number, поэтому вызов метода может иметь место.

EDIT: В первом случае, вы создали строку, как этот первый var str = new String(), но потом вы изменили его str = "asdf", а затем присваивается свойству str.var_1 = "1234".

Конечно, это не сработает, потому что когда вы назначили str = "asdf", str стал примитивным типом, и экземпляр объекта, который был изначально создан, теперь исчез, и вы не можете добавлять свойства к примитивам.

Во втором случае он не выводил undefined, как вы сказали, я тестировал его в Firebug, и все работало правильно.

EDIT 3:

Строковые литералы (обозначаемые двойные или одинарные кавычки) и строки возвращаются из строки вызовов в контексте не-конструктор (то есть, без использования нового ключевого слова) примитивные строки.

Это взято из MDN Documentation, когда вы используете строку как то var p = String(3) это становится функцией преобразования, а не конструктор и возвращает элементарную строку, как вы можете видеть из приведенной выше цитаты.

Что касается вашего второго комментария, я не понял, как был бросил вызов мой комментарий, потому что если вы пытаетесь console.log(p.pr) вы получите undefined что доказывает p примитивный тип, а не объект.

+0

Почему использование конструктора имеет значение? – 1252748

+1

@thomas Поскольку при использовании конструктора возвращается числовой объект, как вы можете видеть, набрав 'console.log (typeof num)'. –

+0

Каким будет преимущество при создании нового номера объекта? Есть ли причина, по которой новый Number() не создает примитивный номер? – 1252748

2

Если массив является только объектом таким же образом, строка или число является объектом,

Массив отличается от строки, числа, булевы, утратившим неопределенными. Массив - это объект, а остальные в списке - примитивные значения. Вы можете добавлять свойства к массиву точно так же, как и с любым другим объектом, что бы ни отличалось тем, что делает специальные массивы (свойство длины, о котором вы упомянули, например). Вы не можете добавлять свойства или методы вызова в примитивные значения.

В предыдущем ответе this я рассказал об использовании оберток объектов над примитивными значениями. Не стесняйтесь читать его, чтобы узнать больше об обертке объектов. Ниже будет очень короткий пример:

console.log('TEST'.toLowerCase()) // 'test' 

Хотя это может показаться, что метод toLowerCase вызывается на строке «TEST», на самом деле строка автоматически преобразуется в строковый объект и метод toLowerCase называется на объекте String.

Каждый раз, когда вызывается свойство строки, числа или булева, создается новая обертка объекта соответствующего типа, чтобы получить или установить это значение (свойства настройки могут быть полностью исключены браузером, я не уверен об этом).

По вашему примеру:

var num = 1; // primitive value 
num.prop_1 = "a string"; // num is converted to a Number, the prop_1 property is set on the Object which is discarded immediately afterwards 
console.log(num); //1 // primitive value 
console.log(num.prp); // num is converted to a Number, which doesn't have the prp property 

Мой пример:

Number.prototype.myProp = "works!"; 
String.prototype.myFunc = function() { return 'Test ' + this.valueOf() }; 
Boolean.prototype.myTest = "Done"; 


console.log(true.myTest); // 'Done' 
console.log('really works!'.myFunc()); // 'Test really works!' 

var x = 3; 
console.log(x.myProp.myFunc()); // 'Test works!' 

console.log(3['myProp']); // 'works!' 

С другой стороны:

console.log(3.myProp); // SyntaxError: Unexpected token ILLEGAL 

Число не обязательно относиться по-разному, что синтаксис просто путает парсер. Следующий пример должен работать:

console.log(3.0.myProp); // 'works!' 
Смежные вопросы