Что такое {}.prototype?
Часто вижу запись навроде ... = {}.prototype = ... А что это такое и как его можно использовать, не нашел. Подскажите пожалуйста?
|
|
Спасибо за ответ.
Если быть более точным, то записи могут быть разные, например как здесь developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice Выражение навроде, {}.prototype, я написал обобщенно, т.е. это может быть к примеру Function.prototype.call хотя вопрос возник после попытки создать прототип таким способом function root(){} root.prototype = { root :"свойство root" } function user() {} user = {}.prototype = root; var u = new user(); При явном создании функций-конструкторов роль prototype мне кажется понятно, т.е. prototype является ссылкой на свойства родителя. А роль при использовании глобальных, и/или предопределенных объектов в мне не понятна Учитывая, что консоль вернула мне {}.prototype — SyntaxError Object.prototype — Object {} [].prototype — undefined Array.prototype — [] я так понял в моем коде {}.prototype роли как таковой не играет, т.е. я присвоил root сразу и user и {}.prototype, но учитывая, что {}.prototype синтаксическая ошибка, то вызвать я его не могу. С другой стороны не ясно, почему сама запись «user = {}.prototype = root», ошибки не вызвала? Буду признателен за пояснение, или более развернутую информацию, где описывается использование подобных синтаксисов |
Свойство prototype нет смысла задавать объектам (смысл есть только для конструктора). Почему {}.prototype можно использовать только справа от знака "=" я не в курсе.
Array и Object - это конструкторы. При создании объектов через них, прототипом будет соответственно пустой массив и объект. У объекта нет свойства prototype (typeof {}.prototype === "undefined") |
{}.prototype - пишет вообще синтаксическая ошибка
Object.prototype, выдает набор свойств А вот если создать объект, даже пустой, var o = {} то консоль выдает, что это объект, у которого есть одно единственное свойство __proto__, которое обладает свойствами Object.prototype И насколько я понимаю, любой объект наследует свойства у Object.prototype Хотя не могу сказать, что я до конца все понимаю, но как-то так вроде Т.е. если я правильно понимаю, то получается что-то навроде o ссылается Object.prototype, в котором и ищет все свои свойства. |
{}.prototype выдаёт ошибку в консоли, потому что {} - это не только новый объект, но и границы блока. ({}.prototype) в консоли работает верно.
Для предопределённых объектов (типа Object, Array и т.д.) прототипы имеет смысл изменять только в одном случае - эмуляция новых методов ECMAScript для старых браузеров, которые не поддерживают данные методы. Скажем, для функций часто используется .bind - привязка функции к контексту, но IE8 эту функциональность не поддерживает, поэтому приходится писать что-то вроде: if (!Function.prototype.bind) { Function.prototype.bind = function () { //emulating code } } |
Спасибо за ответ.
А Object.prototype и {}.prototype получается разные значения, раз в консоли они выдают мне разный результат И если так, то в чем их разница? |
Object - это конструктор. У него задано свойство prototype.
(new Object()) или, {} - это объект, у него нет свойства prototype. У него есть только скрытая ссылка на прототип - __proto__ (не во всех js-движках доступно), которая ссылается на prototype конструктора. Еще раз - задавать prototype нужно только констукторам. У объектов нет такого свойства. Sanda, спасибо за пояснение. |
Object -> Object.prototype
Function -> Function.prototype -> Object.prototype Т.е. Object.prototype является своего рода родителем всех объектов (к которым в том числе относятся и функции), как предопределенных, так и нет. Сначала свойства и методы ищутся у самого объекта, а потом по порядку у всех его прототипов, в том числе пока не дойдут до Object.prototype. Правильно я понимаю? Предполагаю даже, что конструкторы создаются именно за счет того, что в Function.prototype содержатся все необходимые для этого методы и свойства. И если я прав, то было бы не лишним узнать какие именно. Также здесь описано, что можно переопределить свойство Object.prototype. И насколько я понимаю, то же самое можно сделать и для свойств других предопределенных объектов. Не ясно только, как это все происходит, т.е. как мне назначить скажем новое свойство или метод, а самое главное, проверить и посмотреть (убедиться), что все получилось. |
Подскажите, пожалуйста
Например я создаю метод для Object.prototype Object.prototype.forin = function(){var result = ""; for(i in this) {result += i + ": "+this[i] +"\n"} return result;} var ob = {a:"a",b:"b"} alert(ob.forin()); Я могу увидеть этот метод если наберу в консоли Object.prototype Могу ли я как-то по другому получить доступ к его свойствам и методам? Например for(i in Object.prototype) document.write( i+ ": '" + Object.prototype[i] + "', <br>"); Не получается. Вопрос второй. Как я могу посмотреть те же свойства и методы (пусть даже через консоль) у других предопределенных объектов, например Array.prototype и Function.prototype? Включая и предопределенные методы Вопрос третий. Вышеуказанный метод, который я создал выводит не совсем то, что я хочу a: a b: b forin: function (){var result = ""; for(i in this) {result += i + ": "+this[i] +"\n"} return result;} а мне нужно получить только a: a b: b Как этого добиться? |
Цитата:
Object.prototype.forin = function(){var result = ""; for(i in this) {if (!this.hasOwnProperty(i)) continue;result += i + ": "+this[i] +"\n"} return result;} var ob = {a:"a",b:"b"} alert(ob.forin()); |
Спасибо, т.е. если я правильно понимаю, то forin выводится т.к. он является как бы предопределенным свойством для всех Объектов.
ob -> Object.prototype. Неясно только по-какому правилу не выводятся предопределенные свойства Object., навроде скажем call, или bind. Ведь они тоже являются свойствами Object.prototype? |
Я на всякий случай повторюсь - НЕ НАДО добавлять базовым сущностям новые методы. Единственное исключение - методы, включённые в стандарт, но не поддерживаемые старыми браузерами.
Ответы на первый и второй вопрос - нет (по крайней мере, мне сей способ неизвестен). У методов и полей есть скрытое свойство enumerable, отвечающее за то, будет ли данный метод считаться в for..in-цикле. У стандартных объектов все предопределённые методы имеют enumerable = false. Ответ на третий вопрос. Вернее, сначала комментарий. Именно поэтому и не надо расширять стандартные объекты - порой случаются неожиданные казусы вроде этого (: Касаемо же вывода - нужно взять за правило в любом for..in ставить проверку hasOwnProperty для отсечения "привнесённых" методов/полей. var greeter = function () {}; //свойство в прототипе родителя greeter.prototype.greet = function() {alert('Hello');}; var byer = new greeter(); //собственное свойство потомка byer.bye = function () {alert('Bye'); }; var result1 = "With hasOwnProperty:\n"; for (key in byer){ if (byer.hasOwnProperty(key)) { result1 += key + ': ' + byer[key].toString() + "\n"; } } alert(result1); //выводит только собственные свойства объекта result2 = "Without hasOwnProperty:\n"; for (key in byer){ result2 += key + ': ' + byer[key].toString() + "\n"; } alert(result2); //выводит все enumerable=true свойства объекта |
Спасибо за пояснение, только все-таки мне немного не ясно, а что же тогда это
alert(Object.prototype.constructor.__proto__.apply); |
А это добрый дядя FF (ну или там Chrome) раскрывает скрытый prototype через __proto__. Попробуйте запустить, например, в IE8.
Ну или я не понял вопроса. Вообще, судя по коду, это стандарный Function.prototype.apply, вытащенный через одно место. alert(Function.prototype.apply === Object.prototype.constructor.__proto__.apply); |
С proto я понял, но оно, кстати, сработало везде кроме ie8, более поздних версий под рукой не было.
Если в хроме набрать Object.prototype, то можно посмотреть все свойства и методы ему свойственные. Так вот, если задать метод через Object.prototype.apply = то в у меня появляется новый метод apply А если сделать, при этом если проследить цепочку, то старый метод сохраняется, но его можно изменить так Object.prototype.constructor.__proto__.apply = При этом согласно http://learn.javascript.ru/classes#...-в-javascript Я ожидал что Function.prototype.apply, должна находится внизу цепочки, Как же оно все на самом деле то? |
Подскажите, функция
Function.prototype.bind - эмулирует свойство, но при этом будет доступно при переборе свойств через for in. Также будут доступны свойства вновь созданные свойства в Object.prototype. При этом свойства Function.prototype и все свойства Object.prototype будут доступны при переборе любого конструктора. А что если мне нужно сэмулировать bind, но мне эти свойства не нужны. Могу я засунуть в какую-то свою функцию-конструктор, MyFunction.prototype к примеру и использовать ее как обычный bind? |
А самое главное могу ли я как-то объединить по принципу прототипов две замкнутые функции т.е.
Есть функция конструктор a1 = new function(i){ function a_privar(e) { return "a_privat"; } return { aa: function (d) { alert(d+a_privar()+(++i));} } }(3) a1.aa("0-"); Мне нужно расширить функцию функцией b1 b1 = function(){ function b_privat(e) { return "b_privat"; } return { bb: function (d) {alert(d+b_privat()+(++ii)); } }}() Как это сделать? |
Object.defineProperty(Object.prototype, 'prop1', {enumerable: true,value: 'bla1'}) Object.defineProperty(Object.prototype, 'prop2', {enumerable: false,value: 'bla2'}) for (var prop in Object.prototype) alert(prop); |
Спасибо, но этот метод к сожалению не для Ie8.
|
Часовой пояс GMT +3, время: 05:20. |