Большой вызов! Сколько уровней вы прошли по JS интерфейсу?

внешний интерфейс JavaScript
Большой вызов! Сколько уровней вы прошли по JS интерфейсу?

Эта статья приняла участие"Проект "Звезда раскопок"", чтобы выиграть творческие подарочные пакеты и бросить вызов творческим поощрениям.

предисловие

Базовые знания действительно интересны, 10 тем базовых знаний, пожалуйста, приходите и сражайтесь!

1. a.x = a = {n:2}

var a = {n:1};
a.x = a = {n:2};

// 求a.x
alert(a.x); 

Разобрать

JavaScript всегда рассчитывается в строгом соответствии с орденом слева направо на выражение.

Когда a.x, наконец, выполняет назначение, он сохраняет原来a的引用, При предупреждении a является переназначенным a.


var a = {n:1}, ref = a;
a.x = a = {n:2};
console.log("a:", a); 
console.log("ref:",ref);

image.png

2. Побитовое ИЛИ целочисленная часть

оценивать:

100.8 | 0   
-101.6 | 0   
8589934592.8 | 0

Разобрать

Побитовые операторы обрабатывают числа как 32-разрядные целые числа со знаком, а диапазон 32-разрядных целых чисел составляет-2147483648 ~ 2147483647.

Для чисел, превышающих диапазон 32-разрядных целых чисел со знаком, побитовые операции ИЛИ неверны.

 2147483647.1 | 0  //  2147483647 正确
 2147483648.1 | 0  // -2147483648 错误
-2147483648.1 | 0  // -2147483648 正确
-2147483649.1 | 0  //  2147483647 错误

Точно так же мы можем использовать~~Чтобы взять целую часть, конечно, остается проблема неточности за пределами диапазона.

~~ 100.8 // 100  正确
~~ 2147483649.1  // -2147483647  错误

Отвечать

100.8 | 0    // 100
-101.6 | 0   // -101
8589934592.8 | 0  // 0

3. Волшебная оценка

var x = "global";
function log1(){
    var x = "local";
    return eval("x")
}

function log2(){
    var x = "local";
    return window.eval("x")
}

function log3(){
    var x = "local";
    var fn = eval
    return fn("x")
}

function log4(){
    var x = "local";
    return (0, eval)("x")
}

log1();
log2();
log3();
log4();

Разобрать

Функция eval имеет возможность доступа ко всей области видимости, в которой она была вызвана.
Косвенные вызовы, такие как привязка функции eval к ​​другому имени переменной, вызывают функцию по имени переменной, и код теряет возможность доступа ко всем локальным областям.

(0, eval)Это также косвенный вызов eval.

log1();   // local
log2();   // global
log3();   // global
log4();   // global

Отвечать

4. Как много вы знаете об удалении

delete null;
delete undefined;

Разобрать

undefinedявляется глобальным свойством в реализации, иnullявляется ключевым словом.

Oject.getOwnPropertyDescriptor(global, 'undefined')

截图_20212014102047.png

null не может запрашивать информацию описания глобально:

Object.getOwnPropertyDescriptor(global, 'null')

截图_20212114102114.png

результат

delete null; // true
delete undefined; // false

5. Преобразование типов

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.valueOf = function () {
    return this.age;
}
Person.prototype.toString = function () {
    return this.name
}
Date.prototype.valueOf = function () {
    return this.getTime()
}
Date.prototype.toString = function () {
    return this.getTime() + ""
}

var person = new Person("tom", 100);
console.log(person + 10);
console.log(`${person}`)
console.log("" + person)

var date = new Date(2001, 0, 0);
console.log(date + 0, typeof (date + 0))
console.log(date + date.getTime());

анализировать

Объекты преобразуются в примитивные типы данных

  • Symbol.toPrimitive имеет приоритет
  • Object.prototype.toString, если ожидается преобразование в строку
  • Если нет ожидаемой строки, идем Oject.prototye.valueOf, идем Object.prototype.toString,Особым случаем является тип Date, сначала toString, затем valueOf.

Обратите внимание на два момента

  1. 预期转为字符串такие слова, как`${person}`
  2. Дата особенная и предпочтительнее, чем String

результат

var person = new Person("tom", 100); 
console.log(person + 10);  // 110
console.log(`${person}`)   // tom
console.log("" + person)   // 100

var date = new Date(2001, 0, 0);
console.log(date + 0, typeof (date + 0)) 
// 9781920000000 string
console.log(date + date.getTime());
// 978192000000978192000000

6. Длина функции

function add(num1, num2, num3=1, ...args){ 
}
const boundAdd = add.bind(null, 10);
console.log(boundAdd.length)

Анализ проблемы

  1. Параметры со значениями по умолчанию, длина не учитывается
  2. Остальные параметры не учитываются в длине
  3. После привязки уменьшите соответствующую длину

Отвечать

console.log(boundAdd.length) // 1

7. Смысл этого

var value = 1;

var foo = {
  value: 2,
  bar: function () {
    return this.value;
  }
}

console.log(foo.bar());
console.log((foo.bar)());
console.log((foo.bar = foo.bar)());
console.log((false || foo.bar)());
console.log((foo.bar, foo.bar)());

Разобрать

В спецификации ES ссылочный тип (тип ссылки) имеет способ получения соответствующего значения: GetWalue. Простое моделирование GetValue:

var foo = 1;

var fooReference = {
    base: EnvironmentRecord,
    name: 'foo',
    strict: false
};

GetValue(fooReference) // 1;

GetValue возвращает реальное значение свойства объекта, но будьте осторожны:Вызов GetValue вернет конкретное значение вместо ссылки

Если эта тема вызываетGetValue, то его область действия становится глобальной.

(foo.bar)Операция значения не вызывается, а остальные вызывают операцию значения.

Подробнее:Углубленная интерпретация JavaScript из спецификации ECMAScript.

Отвечать

console.log(foo.bar());   // 2
console.log((foo.bar)());  // 2
console.log((foo.bar = foo.bar)());  // 1
console.log((false || foo.bar)());   // 1
console.log((foo.bar, foo.bar)());   // 1

8. Передача параметров

function test(param1, param2, param3) {
    param1 = "new param1";
    param3  = "new param3"

    console.log(param1 == arguments[0]);
    console.log(param3 == arguments[2]);
}


function test_strict(param1, param2, param3) {
    "use strict"
    param1 = "new param1";
    param3  = "new param3"

    console.log(param1 == arguments[0]);
    console.log(param3 == arguments[2]);
}

test('param1', 'param2')
test_strict('param1', 'param2');

Разобрать

В нестрогом режиме: переданные параметры, фактические параметры и значения аргументов будут общими.Если они не переданы, значения фактических параметров и аргументов не будут разделены.

В строгом режиме аргументы и аргументы не передаются.

Отвечать

test('param1', 'param2')
test_strict('param1', 'param2');
// true
// false
// false
// false

9. Добавьте десятичные дроби

(0.1 + 0.2) + 0.3  === 0.1 + (0.2 + 0.3)

Разобрать

Короткий ответ - это точный вопрос.
больше ответовIEEE 754, Числа с плавающей запятой двойной точности (64 бита), представленные 1 в качестве бита знака, 11 битов экспоненты и 52 бита мантиссы.

С помощью:Woohoo.binary convert.com/result_neither…

0.1 0-01111111011-1001100110011001100110011001100110011001100110011010
0.2 0-01111111100-1001100110011001100110011001100110011001100110011010
0.3 0-01111111101-0011001100110011001100110011001100110011001100110011

Конечно, расчет еще в нескольких шагах

  • На заказ (большой порядок для небольшого порядка)
  • цифровая арифметика
  • нормализация результата
  • округление
  • удалить чек

Конечно, в этом вопросе двух последних не существует. Подробности — в другой статье!

Отвечать

(0.1 + 0.2) + 0.3  === 0.1 + 0.2 + 0.3  // false

0.6000000000000001 === 0.6 // false

10. Автодополнение

Выходное значение следующего кода

var a = [[1,2],2,3]
console.log(a)
[0,2,3].map(v=> console.log(v*v))
console.log(a)

Разобрать

JavaScript может разумно вставлять точки с запятой, но есть 5 проблемных символов, требующих пристального внимания:(,[, +, -, /, как начало строки кода, может привести к непредвиденным ситуациям, поэтому ставьте точку с запятой в конце кода, чтобы убедиться в его правильности.

Отвечать

image.png

напиши в конце

Группа Технической биржи GOиди сюда. Или добавьте мое WeChat-похоронное облако, возьмите меня и учитесь вместе.

Цитировать

Углубленная интерпретация JavaScript из спецификации ECMAScript.
>