2016-02-19 1 views
2

Так что я создаю некоторые цепочки, которые выполняют простые проверки типов. В настоящее время, я должен назвать свои функции, как это:API: Создание функций конструктора без привязки к скобкам в JavaScript

Proceed().if('someString').is.a('string'); 

Но я действительно хочу для моего API, чтобы выглядеть следующим образом:

proceed.if('someString').is.a('string'); 

Обратите внимание, что во втором примере кода открывающая и закрывающая скобки отсутствуют при первом вызове функции.

Как вы можете видеть из приведенной ниже коды, я уже понял, как получить is и a работать, но я не могу показаться, чтобы найти способ, чтобы удалить скобки из функции Proceed().

Вот пример код, который работает:

function Proceed() { 
    if (!(this instanceof Proceed)) { 
     return new Proceed(); 
    } 
    this.target = ""; 
} 

Proceed.prototype.if = function (target) { 
    this.target = target; 
    return this; 
} 

Proceed.prototype.a = function (type) { 
    console.log(this.target + ' === ' +type, typeof this.target === type); 
}; 

Object.defineProperty(Proceed.prototype, 'is', { 
     get: function() { 
      return this; 
     } 
    }); 


Proceed().if('someString').is.a('string'); // true 
Proceed().if('someString').is.a('function'); // false 


// Everything Above this line Works! 

И теперь, моя попытка удалить скобки из Proceed() выглядит следующим образом:

Object.defineProperty(Proceed.prototype, 'proceed', { 
    set: function(){}, 
    get: function(){ 
    return Proceed(this); 
    }, 
    configurable: true 
}); 

proceed.if('someString').is.a('string'); // ReferenceError 
proceed.if('someString').is.a('function'); // ReferenceError 

Ошибка я получаю от здесь это:

Uncaught ReferenceError: proceed is not defined

Если я поменяю Proceed.prototype на Object.prototype, тогда я могу заставить его работать, но это значит, что я расширил собственный объект, что может быть проблематичным.

Так кто-нибудь знает, как я могу это сделать без опасного расширения родного объекта? Что я здесь делаю неправильно?

Here is a jsFiddle with the above code samples.

Любая помощь приветствуется.

UPDATE # 1 Этот код разрабатывается в качестве узлового модуля, так что не будет никакого доступа к window объекта браузера.

+0

Не думаю, что вы можете без расширения объекта или окна. Я тестировал с окном вместо Proceed: https://jsfiddle.net/Lw29zyf1/4/ –

ответ

2

Вы должны начать с переменным Экземпляром многозначными:

var proceed = new Proceed(); 

И сделать это в цепочке, вы должны возвращать новые экземпляры из ваших методов вместо мутирует «статический» proceed объекта:

function Proceed(target) { 
    this.target = arguments.length ? target : ""; 
} 

Proceed.prototype.if = function (target) { 
    return new Proceed(target); 
} 

Или, в общем, вам нужно сделать proceed.if фабрикой, которая возвращает Proceed экземпляров, независимо от того, является ли proceed уже одним или только обычным объектом.

(jsfiddle demo)

+0

Спасибо, что нашли время, чтобы посмотреть на это! На первый взгляд, похоже, он работает, но также имеет побочный эффект не возвращать новые экземпляры для каждого вызова. Каждый раз, когда я вызываю 'continue.if() ...' Мне нужен новый экземпляр 'Proceed', но в вашей демонстрации я обнаружил, что каждый последующий вызов сохранял значения из предыдущего вызова, как будто' continue' был просто Переменная. Я обновил демо с демонстрацией. Обратите внимание на инструкции console.log() внизу: https://jsfiddle.net/Lw29zyf1/6/. Еще раз спасибо, я очень ценю вашу помощь! – radiovisual

+0

К сожалению, [эта скрипка] (https://jsfiddle.net/Lw29zyf1/5/) имела два метода 'if', ваша старая реализация переписывала рабочий из моего ответа. Исправлена. – Bergi

+0

Красивая! Это подходит для меня. Большое спасибо! Вы просто помогли мне [закрыть этот билет] (https://github.com/radiovisual/detonate/issues/1) в моей экспериментальной библиотеке. Очень признателен. – radiovisual

0

Изменение:

Object.defineProperty(Proceed.prototype, 'proceed', { 

в

Object.defineProperty(window, 'proceed', { 

обновленный скрипкой: https://jsfiddle.net/Lw29zyf1/4/

Таким образом, вы будете иметь "продолжить" переменную в окне рамки.

+0

Да, это помогает выполнить работу! Тем не менее, мне нужно это, чтобы работать в автономной среде узла, где у меня не будет доступа к объекту окна. Я обновлю свой вопрос, чтобы сообщить читателям, что этот код должен работать как на узле, так и в браузере. Благодаря! – radiovisual

+0

Но это хороший ответ для тех, кто хочет сделать что-то подобное в среде браузера. Благодаря! – radiovisual

0

Пожалуйста, смотрите, если ниже код какой-либо помощи

var proto = Object.create(null); 
proto.a = function(type) { 
console.log(this.target + ' === ' + type, typeof this.target === type); 

}; 

Object.defineProperty(proto, 'is', { 
    get: function() { 
     return this; 
    } 
}); 

proto.if = function(target) { 
this.target = target; 
return this; 

}; 


var proceed = Object.create(proto); 

proceed.if('someString').is.a('string'); 
+0

Можете ли вы объяснить, почему вы использовали 'Object.create', пожалуйста? – Bergi

+0

Потому что это единственный способ, которым мы можем назначить прототип объекту без использования функций-конструкторов. –

+0

Это работает в том смысле, что * * создает желаемый API, но ваш пример создает объект вместо использования функций, и вопрос был сосредоточен на функциях. Однако это делает работу, если я использую объекты, поэтому я ценю ваш вклад! – radiovisual

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