Попробуйте следующее:
.glass:before {
content: "";
position: fixed;
left: 0;
right: 0;
z-index: 1;
background: rgba(0,0,0,0.8);
display: block;
width:100%;
height: 100%;
-webkit-filter: blur(30px);
-moz-filter: blur(30px);
-o-filter: blur(30px);
-ms-filter: blur(30px);
filter: blur(30px);
}
blockquote>// This is bad: //foo.__proto__.bar = bar; // But this is okay Foo.prototype.bar = bar;
Нет. Оба делают то же самое (как
foo.__proto__ === Foo.prototype
), и оба прекрасны. Они только создают свойствоbar
на объектеObject.getPrototypeOf(foo)
.То, о чем говорится в заявлении, это присвоение самому свойству
__proto__
:function Employee() {} var fred = new Employee(); // Assign a new object to __proto__ fred.__proto__ = Object.prototype; // Or equally: Object.setPrototypeOf(fred, Object.prototype);
предупреждение на странице
Object.prototype
более подробно:Мутирование [[Prototype]] объекта по характеру, как оптимизируются современные JavaScript-движки доступ к ресурсам, очень медленная операция
blockquote>Они просто заявляют, что изменяет цепочку прототипов уже существующего объекта убивает оптимизацию . Вместо этого вы должны создать новый объект с другой цепочкой прототипов через
Object.create()
.Я не мог найти явную ссылку, но если мы рассмотрим, как скрытые классы V8 , мы можем видеть, что здесь может произойти. При изменении последовательности прототипов объекта изменяется его внутренний тип - он не просто становится подклассом, как при добавлении свойства, но полностью заменяется. Это означает, что все исправления поиска свойств очищаются, и предварительно скомпилированный код нужно будет отбросить. Или он просто возвращается к неоптимизированному коду.
Некоторые заметные цитаты:
- Брендан Эйх (вы его знаете) сказал Writable __proto__ is гигантская боль для реализации (должна быть сериализована для проверки цикла) и создает всевозможные угрозы путаницы.
- Брайан Хакетт (Mozilla) сказал : разрешая скриптам мутировать прототип практически любого объекта, затрудняет рассуждение о поведении скрипта и делает VM, JIT и реализация анализа более сложная и более сложная. Вывод типа имеет несколько ошибок из-за изменчивого __proto__ и не может поддерживать несколько желательных инвариантов из-за этой функции (т.е. «наборы типов содержат все возможные типы объектов, которые могут реализоваться для var / property» и «JSFunctions имеют типы, которые также являются функциями», ).
- Джефф Уолден сказал : мутация прототипа после создания с его неустойчивой дестабилизацией производительности и воздействием на прокси и [[SetInheritance]]
- Эрик Корри (Google) сказал, что : я не ожидаю, что большой прирост производительности приведет к тому, что proto не будет перезаписываться. В неоптимизированном коде вам нужно проверить цепочку прототипов, если объекты прототипа (а не их личность) были изменены. В случае оптимизированного кода вы можете вернуться к неоптимизированному коду, если кто-то пишет в proto. Таким образом, это не принесло бы такой большой разницы, по крайней мере, в V8-Crankshaft.
- Эрик Фауст (Mozilla) сказал . Когда вы устанавливаете __proto__, вы не только разрушаете любые шансы, которые вы, возможно, имели для будущих оптимизаций от Ion на этом объекте, но также заставляете движок, чтобы обходить все остальные части вывода типа (информация о значениях возвращаемых функций или значений свойств, возможно), которые, по их мнению, знают об этом объекте и говорят им не делать много предположений, что предполагает дальнейшую деоптимизацию и, возможно, аннулирование существующего jitcode. Изменение прототипа объекта в середине исполнения на самом деле является неприятным кувалдой, и единственный способ, которым мы должны избегать неправильного, - это безопасно играть, но безопасный медленный.
__proto__
/ setPrototypeOf
не совпадают с назначением прототипа объекта. Например, когда у вас есть функция / объект с назначенными ей членами:
function Constructor(){
if (!(this instanceof Constructor)){
return new Constructor();
}
}
Constructor.data = 1;
Constructor.staticMember = function(){
return this.data;
}
Constructor.prototype.instanceMember = function(){
return this.constructor.data;
}
Constructor.prototype.constructor = Constructor;
// By doing the following, you are almost doing the same as assigning to
// __proto__, but actually not the same :P
var newObj = Object.create(Constructor);// BUT newObj is now an object and not a
// function like !!!Constructor!!!
// (typeof newObj === 'object' !== typeof Constructor === 'function'), and you
// lost the ability to instantiate it, "new newObj" returns not a constructor,
// you have .prototype but can't use it.
newObj = Object.create(Constructor.prototype);
// now you have access to newObj.instanceMember
// but staticMember is not available. newObj instanceof Constructor is true
// we can use a function like the original constructor to retain
// functionality, like self invoking it newObj(), accessing static
// members, etc, which isn't possible with Object.create
var newObj = function(){
if (!(this instanceof newObj)){
return new newObj();
}
};
newObj.__proto__ = Constructor;
newObj.prototype.__proto__ = Constructor.prototype;
newObj.data = 2;
(new newObj()).instanceMember(); //2
newObj().instanceMember(); // 2
newObj.staticMember(); // 2
newObj() instanceof Constructor; // is true
Constructor.staticMember(); // 1
Кажется, что все фокусируются только на прототипе и забывают, что функции могут иметь назначенные ему члены и создаваться после мутации , В настоящее время нет другого способа сделать это, не используя __proto__
/ setPrototypeOf
. Едва ли кто-либо использует конструктор без возможности наследования от родительской конструкторской функции, а Object.create
не может служить.
И плюс, это два вызова Object.create
, которые в настоящий момент являются нечестивыми медленными в V8 (оба браузера и Node), что делает __proto__
более жизнеспособным выбором
Да. prototype = так же плохо, поэтому формулировка «независимо от того, как это делается». prototype - псевдообъект для расширения функциональности на уровне класса. Его динамическая природа замедляет выполнение скриптов. С другой стороны, добавление функции на уровне экземпляра требует гораздо меньших затрат.
Здесь приведен пример с использованием узла v6.11.1
NormalClass: нормальный класс с прототипом без редактирования
PrototypeEdited: класс с отредактированным прототипом (test()
функция добавлена)
PrototypeReference: класс с добавленной функцией прототипа test()
, который ссылается на внешнюю переменную
Результаты:
NormalClass x 71,743,432 ops/sec ±2.28% (75 runs sampled)
PrototypeEdited x 73,433,637 ops/sec ±1.44% (75 runs sampled)
PrototypeReference x 71,337,583 ops/sec ±1.91% (74 runs sampled)
Как вы можно видеть, прототип отредактированного класса - это путь быстрее обычного класса. Прототип, который имеет переменную, относящуюся к внешнему, является самым медленным, но это интересный способ редактирования прототипов с уже заданной переменной
Источник:
const Benchmark = require('benchmark')
class NormalClass {
constructor () {
this.cat = 0
}
test () {
this.cat = 1
}
}
class PrototypeEdited {
constructor () {
this.cat = 0
}
}
PrototypeEdited.prototype.test = function () {
this.cat = 0
}
class PrototypeReference {
constructor () {
this.cat = 0
}
}
var catRef = 5
PrototypeReference.prototype.test = function () {
this.cat = catRef
}
function normalClass () {
var tmp = new NormalClass()
tmp.test()
}
function prototypeEdited () {
var tmp = new PrototypeEdited()
tmp.test()
}
function prototypeReference () {
var tmp = new PrototypeReference()
tmp.test()
}
var suite = new Benchmark.Suite()
suite.add('NormalClass', normalClass)
.add('PrototypeEdited', prototypeEdited)
.add('PrototypeReference', prototypeReference)
.on('cycle', function (event) {
console.log(String(event.target))
})
.run()