07.12.2014, 17:06
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
krutoy, возьми мой пример и покажи, что не так
|
|
07.12.2014, 17:19
|
Профессор
|
|
Регистрация: 09.11.2014
Сообщений: 610
|
|
Сообщение от bes
|
возьми мой пример и покажи, что не так
|
вот в этой строке
cache[stamp] = fn.apply(this, arguments);
в ключ записывается не объект, а лишь текстовое представление его "верхушки", первого хеша. В дальнейшем, когда ты делаешь проверку, у тебя следующий "отпечаток", при сравнении строк даст true, хотя объекты, записанные туда, могут быть другими.
o1={a: 1}
o2={a: 1}
textRepresent1=JSON.stringify(o1)
textRepresent2=JSON.stringify(o2)
console.log(
o1===o2,
textRepresent1===textRepresent2
)
// false true
У тебя из кеша будет извлечено не то, что ты ожидаешь.
Последний раз редактировалось krutoy, 07.12.2014 в 17:27.
|
|
07.12.2014, 17:27
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
хакер
Сообщение от krutoy
|
bes,
Это идет, видимо, от общего, превратного понимания JS, в массе. JS является чистейшим ООП языком, в стиле смолтока или селфа, то есть, ООП в хорошем смысле этого слова. В подобных семантиках, надо рассматривать ключ объекта, как предикат, определяющий, может ли объект принять данное сообщение, "знает" ли он данное определение.
|
JS - мультипарадигменный язык.
бахать "с икретные свойства" примитивам для того , чтобы их "опознать" - это уже не мемоизация, а геморизация.
ты взял этот способ из книги Фленегана?. (да, мы все его читали)
|
|
07.12.2014, 17:43
|
Профессор
|
|
Регистрация: 09.11.2014
Сообщений: 610
|
|
Сообщение от melky
|
мультипарадигменный
|
Этот базворд я слышал раз тысячу, но до сих пор не понял, что в него вкладывается. В частности, многие кукарекают о якобы, поддержке JS ФП, чего и близко нет в реальности (и не нужно), если следовать современной трактовке, где во главе угла иммутабельность.
Сообщение от melky
|
примитивам
|
А, если речь только лишь о примитивах, тогда ок, только тогда надо отдельно указывать, что массивы, регекпы, функции, объекты, объекты строк, объекты чисел и прочая и прочая, то есть, пости все, иными словами, запрешены в качестве аргументов.
Сообщение от melky
|
способ из книги Фленегана
|
Я ни о каком способе не писал, я лишь сказал, что ф-ция говно. А Фленагана я толком не читал, не люблю тягомотину.
|
|
07.12.2014, 17:49
|
Профессор
|
|
Регистрация: 09.11.2014
Сообщений: 610
|
|
Сообщение от melky
|
бахать "сикретные свойства" примитивам для того , чтобы их "опознать" - это уже не мемоизация, а геморизация.
|
Кстати, никакого геммороя тут нет, достаточно расширить бызовые типы, это буквально несколько строк кода, и никакой сложности. Только я об этом не говорил ничего в данном треде.
и я не совсем понял, что ты имеешь в виду. Если ты расшитяешь именно примитив, то ты делаешь это так
String.prototype.foo=1
и, в этом случае, у тебя все строки будут иметь св-во foo. Если же ты делаешь
foo=new String("foo")
foo.foo=1
alert(foo.foo)
// 1
Ты расширяешь не примитив, а конкретный строковый объект.
Последний раз редактировалось krutoy, 07.12.2014 в 17:59.
|
|
07.12.2014, 18:07
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от krutoy
|
вот в этой строке
cache[stamp] = fn.apply(this, arguments);
в ключ записывается не объект, а лишь текстовое представление его "верхушки", первого хеша. В дальнейшем, когда ты делаешь проверку, у тебя следующий "отпечаток", при сравнении строк даст true, хотя объекты, записанные туда, могут быть другими.
o1={a: 1}
o2={a: 1}
textRepresent1=JSON.stringify(o1)
textRepresent2=JSON.stringify(o2)
console.log(
o1===o2,
textRepresent1===textRepresent2
)
// false true
У тебя из кеша будет извлечено не то, что ты ожидаешь.
|
всё хорошо, но речь шла о том, что
Сообщение от y0uix
|
0) Создается некоторая функция, принимающая N аргументов;
1) Создается кэширующая функция, которая принимает вышеуказанную в качестве фунарга и дальше с возвращенным ей значением мы можем работать следующим образом:
- если такая функция-обертка вызывается с новым набором аргументов, то выполняется оригинальная функция;
- в противном случае, если вызов с такими аргументами уже был, то возвращается закэшированный результат, без вызова.
|
поэтому и пример ниже не рассчитан на решение тех задач, о которых ты говоришь
function f(obj) {
return obj.a = 2;
};
function cacheFn(fn) {
var cache = {};
return function () {
var stamp = JSON.stringify(arguments);
console.log(cache);
if (!(stamp in cache)) {
cache[stamp] = fn.apply(this, arguments);
console.log("call: " + cache[stamp]);
}
console.log("cache: " + cache[stamp] + "\n\n");
return cache[stamp];
}
}
var cacheF = cacheFn(f);
var o1 = {a: 1};
var o2 = {a: 1};
cacheF(o1);
cacheF(o2);
console.log("o1:");
console.log(o1);
console.log("o2:");
console.log(o2);
|
|
07.12.2014, 18:09
|
Профессор
|
|
Регистрация: 09.11.2014
Сообщений: 610
|
|
Сообщение от bes
|
с новым набором аргументов
|
bes,
Сообщение от krutoy
|
только тогда надо отдельно указывать, что массивы, регекпы, функции, объекты, объекты строк, объекты чисел и прочая и прочая, то есть, почти все, иными словами, запрешены в качестве аргументов.
|
|
|
07.12.2014, 18:14
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от krutoy
|
Сообщение от krutoy
только тогда надо отдельно указывать, что массивы, регекпы, функции, объекты, объекты строк, объекты чисел и прочая и прочая, то есть, почти все, иными словами, запрешены в качестве аргументов.
|
нет, не запрещены, речь шла только о работе с возвращённым значением, то, о чём говоришь ты, другая задача
|
|
07.12.2014, 18:18
|
Профессор
|
|
Регистрация: 09.11.2014
Сообщений: 610
|
|
bes,
Нет, ты опять не понял. Задача твоей кэширующей ф-ции в том, чтобы "понять", была ли данная функция (которая в замыкании), уже вызвана с данными аргументами. Именно этого она не делает, точней делает, но только с примитивами. Она не может по этой "псевдосигнатуре" объекта определить, был ли данный объект уже в качестве аргумента, или нет, потому что разные объекты могут давать одинаковый отпечаток.
o1=Object.create({b: 2})
o2=Object.create({b: 3})
o1.a=1
o2.a=1
f=function(o){return o.a+o.b}
function cacheFn(fn) {
var cache = {};
return function () {
var stamp = JSON.stringify(arguments);
console.log(cache);
if (!(stamp in cache)) {
cache[stamp] = fn.apply(this, arguments);
console.log("call: " + cache[stamp]);
}
console.log("cache: " + cache[stamp] + "\n\n");
return cache[stamp];
}
}
theCache=cacheFn(f)
alert(theCache(o1))
alert(theCache(o2))
// {}
// call: 3
// cache: 3
//
//
// 3
// { '{"0":{"a":1}}': 3 }
// cache: 3
//
//
// 3
//
Последний раз редактировалось krutoy, 07.12.2014 в 18:31.
|
|
07.12.2014, 20:12
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от krutoy
|
bes,
Нет, ты опять не понял. Задача твоей кэширующей ф-ции в том, чтобы "понять", была ли данная функция (которая в замыкании), уже вызвана с данными аргументами. Именно этого она не делает, точней делает, но только с примитивами. Она не может по этой "псевдосигнатуре" объекта определить, был ли данный объект уже в качестве аргумента, или нет, потому что разные объекты могут давать одинаковый отпечаток.
o1=Object.create({b: 2})
o2=Object.create({b: 3})
o1.a=1
o2.a=1
f=function(o){return o.a+o.b}
function cacheFn(fn) {
var cache = {};
return function () {
var stamp = JSON.stringify(arguments);
console.log(cache);
if (!(stamp in cache)) {
cache[stamp] = fn.apply(this, arguments);
console.log("call: " + cache[stamp]);
}
console.log("cache: " + cache[stamp] + "\n\n");
return cache[stamp];
}
}
theCache=cacheFn(f)
alert(theCache(o1))
alert(theCache(o2))
// {}
// call: 3
// cache: 3
//
//
// 3
// { '{"0":{"a":1}}': 3 }
// cache: 3
//
//
// 3
//
|
ок, показательный пример
|
|
|
|