Jquery создать прототип из объекта

Hene спросил: 31 июля 2018 в 09:55 в: javascript

Я хотел бы немного обмануть при создании прототипов

, например

var person = {
   name: 'John',
   age: 110,
   gender: 'm',
   ...
};var employee = new Person(person);function Person(args) {
   $.each(args, function(key, value) {
      this[key] = value; // Cannot create property 'key' on number
   });
}console.log(employee.age);

В PHP это можно сделать, например

function __construct() {
    $args = func_get_arg(0);            
    foreach ($args as $key => $value) {
        $this->$key = $value;
    }
    return $this;
}

3 ответа

Есть решение
Aboca ответил: 31 июля 2018 в 10:13

Проблема в вашем коде jQuery заключается в том, что "this" фактически присутствует в каждой области jquery, поэтому для создания прототипа вашего нового экземпляра вам необходимо сделать следующее:

function Person(args) {
    var _this = this;
   $.each(args, function(key, value) {
      _this[key] = value;
   });
}

You также можно добиться этого без использования jQuery:

 function Person(args) {
    for(var key in args){
        this[key] = args[key];
     }
 }
Amit Wagner ответил: 31 июля 2018 в 10:06

проблема в том, что "это" относится к каждой функции, а не к фактическому персонажу. Вы можете изменить его на функцию стрелки, и она будет работать

var person = {
   name: 'John',
   age: 110,
   gender: 'm',
   ...
};

var employee = new Person(person);

function Person(args) {
   $.each(args, (key, value) => { //changed to arrow function to keep this in the same scope
      this[key] = value; // Cannot create property 'key' on number
   });
}

console.log(employee.age);
Jared Smith ответил: 31 июля 2018 в 10:08
Могу добавить, что разница между этой версией и версией PHP для ОП заключается в том, что версия PHP использует цикл вместо функции обратного вызова (так что проблема с ограничением объема не возникает).
Hene ответил: 31 июля 2018 в 10:08
Потрясающие! Спасибо.
Aboca ответил: 31 июля 2018 в 10:09
Обратите внимание, что функции стрелок могут вызвать проблемы совместимости: caniuse.com/#feat=arrow-functions
alexP ответил: 31 июля 2018 в 10:10
Или просто используйте bind(this) $.each(args, function(key, value) { this[key] = value; }.bind(this));
alexP ответил: 31 июля 2018 в 10:11

Используйте bind для получения правильной области

function Person(args) {
   $.each(args, function(key, value) {
      this[key] = value; 
   }.bind(this)); //Use bind for getting the right scope
}