прототип и свойства объектов конструктора

Поскольку [[1,5,10] не является допустимым списком, я предполагаю, что вы имеете в виду [[1,5,10]], то есть список int list . Вы можете создать такой список просто, как только что сделали: [[1,5,10]]. Выполнение этого для произвольного списка int может быть выполнено следующим образом:

fun singleton (xs : int list) = [xs]

val test_1 = singleton [1,5,10]  (* = [[1,5,10]] *)

Конкатенация не произошла, поскольку это синонимично:

- [1,5,10] :: [];
> val it = [[1, 5, 10]] : int list list

То есть список [1,5,10] перед пустым списком.

Это демонстрирует оператор :: (cons). Если вы когда-либо хотите поместить несколько элементов (например, несколько int list s) друг перед другом, это то, что вы называете конкатенацией, и вы используете оператор @ (добавление), например, например:

- [1,5,10] @ [11,15,20]
> val it = [1, 5, 10, 11, 15, 20] : int list

Наконец, есть оператор List.concat, который берет список списков и добавляет их все:

- List.concat [ [1,2,3], [4,5,6], [7,8,9] ];
> val it = [1, 2, 3, 4, 5, 6, 7, 8, 9] : int list

Хорошее упражнение на этом этапе чтобы определить эту рекурсивную функцию:

fun my_concat [] = ...
  | my_concat (xs :: xss) = ...

где xs - первый список в списке списков, а xss - оставшийся список списков.

(Я попытался выделить это, дав xs имя во множественном числе и xss имя во множественном числе.)

10
задан Toon Krijthe 12 February 2009 в 13:28
поделиться

4 ответа

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

Можно работать вокруг проблемы путем ручной установки Obj2.prototype.constructor = Obj2, но этот путь, DontEnum флаг не будет установлен.

Из-за этих проблем это не хорошая идея полагаться constructor для проверки типа: использовать instanceof или isPrototypeOf() вместо этого.


Andrey Fedorov поднял вопрос почему new не присваивается constructor свойство к объекту экземпляра вместо этого. Я предполагаю, что причина этого приезжает следующие строки:

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

Настоящая проблема состоит в том, что JavaScript не имеет никакой встроенной поддержки иерархий наследования. Существует несколько путей вокруг проблемы (Ваш - один из них), другой больше 'в духе' JavaScript было бы следующим:

function addOwnProperties(obj /*, ...*/) {
    for(var i = 1; i < arguments.length; ++i) {
        var current = arguments[i];

        for(var prop in current) {
            if(current.hasOwnProperty(prop))
                obj[prop] = current[prop];
        }
    }
}

function Obj1(arg1) {
    this.prop1 = arg1 || 1;
}

Obj1.prototype.method1 = function() {};

function Obj2(arg1, arg2) {
    Obj1.call(this, arg1);
    this.test2 = arg2 || 2;
}

addOwnProperties(Obj2.prototype, Obj1.prototype);

Obj2.prototype.method2 = function() {};

Это делает множественное наследование тривиальным также.

25
ответ дан 3 December 2019 в 14:00
поделиться

Проверьте ООП Tom Trenka woth ECMAscript, страницу "Inheritance". Все от прототипа наследовано, включая constructor свойство. Таким образом мы должны не повредить его сами:

Obj2.prototype = new Obj1(42);
Obj2.prototype.constructor = Obj2;
9
ответ дан 3 December 2019 в 14:00
поделиться

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

Долгая версия: Конвенция для опытного наследования в JavaScript

Обычно: Вы запутываетесь из-за (a) импедансу не сочетаются между основанным на классах и основанным на прототипе OO и (b) странности конкретной довольно плохой интерпретации JavaScript основанного на прототипе OO.

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

Function.prototype.subclass= function() {
    var c= new Function(
        'if (!(this instanceof arguments.callee)) throw(\'Constructor called without "new"\'); '+
        'if (arguments[0]!==Function.prototype.subclass.FLAG && this._init) this._init.apply(this, arguments); '
    );
    if (this!==Object)
        c.prototype= new this(Function.prototype.subclass.FLAG);
    return c;
}
Function.prototype.subclass.FLAG= new Object();

И вот пример того, как можно было бы использовать его:

// make a new class
var Employee= Object.subclass();

// add members to it
Employee.prototype._LEGS= 2;
Employee.prototype.getLegs= function() {
    return this._LEGS;
};

// optional initialiser, takes arguments from constructor
Employee.prototype._init= function(name) {
    this.name= name;
};

// make a subclass
Manager= Employee.subclass();

// extend subclass method
Manager.prototype._init= function(name, importance) {
    // call base class's method
    Employee.prototype._init.call(this, name);
    this.importance= importance;
}

// all managers are well-known to have three legs
Manager.prototype._LEGS= 3;

// create one
var jake= new Manager('Jake the Peg', 100);
3
ответ дан 3 December 2019 в 14:00
поделиться

Ну, свойство конструктора является свойством как любой другой на прототипе (свойство) Obj1. Если Вы понимаете, как прототипы работают, это могло бы помочь:

>>> obj.hasOwnProperty("constructor")
false

// obj's [[Prototype]] is Obj2.prototype
>>> Obj2.prototype.hasOwnProperty("constructor")
false

// Obj2.prototype's [[Prototype]] is Obj1.prototype
>>> Obj1.prototype.hasOwnProperty("constructor")
true

// Oh?
>>> Obj1.prototype.constructor
Obj1()

Ага! Таким образом, obj не имеет никакого конструктора, JS идет для получения его [[Прототип]] цепочка, полностью от Obj1.prototype.constructor

Я не уверен, почему свойство конструктора только не установлено на объекте, когда Вы используете 'новый'. Могла бы быть причина, или это мог бы просто быть контроль. Так или иначе я склонен избегать его.

1
ответ дан 3 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: