2014-11-09 4 views
0

Я пытался выяснить, существует ли способ типичного процесса расширения объекта, в котором он показывает, что он назначает расширенные свойства прототипу объекта, но привязан к самому методу «extend» на текущем объекте , Я хочу, чтобы свойства были назначены DIRECTLY на текущий объект (т. Е. This.property ", а не" this.extend.property "). Поясню:Расширение объекта Javascript без назначения свойств прототипу?

Насколько я знаю, есть два способа "расширяющие" объект в Javascript:


1) глобальная функция:

function extend(a, b){ 
    for(var key in b) 
     if(b.hasOwnProperty(key)) 
      a[key] = b[key]; 
    return a; 
} 

Я могу тогда запустить этот код, чтобы "расширить" мой App объект:

function App() { 

    extend(this, { 
     command: function() { 
      alert('command!'); 
     } 
    }); 

    console.log(this); 

    return this; 
} 


2) Другой способ расширить это использовать прототип объекта непосредственно, то есть:

Object.prototype.extend = function(obj) { 
    for(i in obj) 
     this[i] = obj[i]; 
}; 

А затем расширить приложение с:

function App() { 

    this.extend({ 
     command: function() { 
      alert('command!'); 
     } 
    }); 

    console.log(this); 

    return this; 
} 


Однако, в то время как функция 'команда' будет теперь доступны в объекте App в обоих случаях выше, оба они все еще показывают, что функция команды является расширением метода «extend» в прототипе приложения. Вывод на консоль из обоих этих шоу: (скрывая другие свойства приложение для краткости):

command: function() { 
    arguments: null, 
    caller: null, 
    length: 0, 
    name: "", 
    prototype: App.extend.command 
} 

Обратите внимание на «App.extend.command»? Мне интересно, есть ли какой-либо способ расширить свойства, чтобы они были атрибутами DIRECT объекта App, так что прототип покажет: «prototype: App.command».

я могу добиться этого, если я назначить СВОЙСТВА непосредственно «это», как:

function App() { 

    this.command = function() { 
     alert('command!'); 
    } 

    console.log(this); 

    return this; 
} 

который выводит:

command: function() { 
    arguments: null, 
    caller: null, 
    length: 0, 
    name: "", 
    prototype: App.command 
} 

Однако, я не хочу, чтобы использовать формат «this.blah = function()» для всех моих свойств. Я хотел бы просто расширить текущий объект с помощью списка свойств JSON, как показано в первых двух примерах. Есть ли способ сделать это, чтобы я мог сохранить свои «новые» объявления функций?

Я добавлю, что предпочтительнее НЕ использовать метод прототипа, так как это добавит свойство extend для ВСЕХ объектов в приложении, что нежелательно для определенных объектов.

Спасибо за чтение!

+1

Это просто отладочное имя, которое не имеет функции в скрипте. Он выбран произвольно вашим devtools. Я думаю, вы можете отказаться от него просто [назвав функцию] (http://blog.niftysnippets.org/2010/03/anonymouses-anonymous.html) – Bergi

+0

Благодарим вас за разъяснение Берги. –

ответ

1

Чтобы получить более четкое представление, вы должны изучить все три способа, которые вы отправили с Firebug в Firefox. То, что делает вывод веб-консолей, не имеет ничего общего с App.prototype, но является иерархией всех функций, вызываемых для настройки command -property. App.prototype вы найдете под App.__proto__.

С вашей стороны 1) вы определенно задали все свойства объекта b как собственных свойств каждого экземпляра приложения (= this). Эти реквизиты, а также функция extend() становится не часть приложения прототип. Вы можете проверить это:

console.log(App.prototype); 
// or you create an instance of App and search for its prototype: 
var myapp = new App(); console.log(Object.getPrototypeOf(myapp)); 

Вы достигаете точно такой же результат, как в виде 1), когда вы включаете функцию extend() в конструкторе App, как это:

function App(b) { 
    if (typeof b == 'object') for (var key in b) this[key] = b[key]; 
    console.log(this); 
    // Aside: you don't need 'return this', it's done automatically when you use 'new App()' 
} 
var obj = {command: function() {alert('command!');}}; 
var myapp = new App(obj); 

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

Только с вашей стороны 2) функция extend() становится собственностью App.prototype, потому что вы это явно определяете. Затем он унаследован ко всем экземплярам приложения.

+0

Спасибо Мартину. Мне нравится также метод # 1, так что он не помещает метод extend во все экземпляры Object (будь то приложение или нет). Наверное, может быть, это просто отладчик Chrome, пытающийся быть конкретным, но я понимаю, что это действительно неважно. Я просто хотел проверить с кем-то, у кого могло бы быть немного больше знаний и посмотреть, может ли я что-то упустить. Спасибо за ваш отзыв. –

Смежные вопросы