浅谈var和delete

好久好久之前,有我的说:我如今写个var,脑海中都会浮现一大堆……,不知所云……数组

变量声明

JavaScript6种变量声明方式中(ES5:var function ES6: let const import class),var能够显示的声明变量,并为变量初始化值(可选),也能够隐式声明。浏览器

删除变量

delete能够用来删除对象的属性,若是:bash

  • delete一个用var声明的变量
  • delete一个没有用var声明的变量
  • 若是加上'use strict' 会如何?

请把下面两段分别放到控制台执行一下函数

var a = 100;b = 200;
delete a;
delete b;
console.log(a);
console.log(b);
复制代码

若是加个use strict,又会如何?ui

'use strict'
var a = 100;b = 200;
delete a;
delete b;
console.log(a);
console.log(b);
复制代码

关于var

语法

var varname1 [= value1] [, varname2 [= value2] ... [, varnameN [= valueN]]];this

描述
  • var声明的变量存在声明提高,JavaScript引擎会在执行代码以前将当前的变量加入到当前执行环境(call stack) 的词法环境中,也就是hosting,变量声明提高

  • 变量能够没有初始值,会保存一个特殊的值 undefined
  • 变量能够重复定义,且能够修改值
  • 变量声明语句从自动提高到所在做用域的顶端
  • 函数内重复定义对函数外无影响(局部变量)
  • 函数内从新赋值对函数外有影响
  • 将未声明的变量赋值(隐式声明),会隐式的将该变量建立为全局变量(我的理解为语言缺陷,否则就不会有 use strict了)
  • 对象上新增的属性,默认configurable为true
var a = {}
Object.getOwnPropertyDescriptor(window,'a')
{value: {…}, writable: true, enumerable: true, configurable: false}
a.b = 1
Object.getOwnPropertyDescriptor(a,'b')
{value: 1, writable: true, enumerable: true, configurable: true}
复制代码
  • 使用var声明的变量,默认configurable为false
var a = 1;
Object.getOwnPropertyDescriptor(window,'a')
{value: 1, writable: true, enumerable: true, configurable: false}
复制代码

关于隐式声明的例子spa

var x = 0;  // x is declared global, then assigned a value of 0

console.log(typeof z); // undefined, since z doesn't exist yet function a() { // when a is called, var y = 2; // y is declared local to function a, then assigned a value of 2 console.log(x, y); // 0 2 function b() { // when b is called x = 3; // assigns 3 to existing global x, doesn't create a new global var
    y = 4;  // assigns 4 to existing outer y, doesn't create a new global var z = 5; // creates a new global variable z and assigns a value of 5. } // (Throws a ReferenceError in strict mode.) b(); // calling b creates z as a global variable console.log(x, y, z); // 3 4 5 } a(); // calling a also calls b console.log(x, z); // 3 5 console.log(typeof y); // undefined as y is local to function a 复制代码

关于delete

语法
delete object.property
delete object['property']
复制代码
返回值

非严格模式下返回true,除了遇到configurable为false和不能删除的状况prototype

说明
  • delete和内存管理无关,内存管理是经过判断引用标记来完成的
  • 若是在对象的原型链上存在同名属性,那么在删除以后,对象将使用原型链中的属性(换句话说,删除只对本身的属性有影响)。
  • 不能从全局做用域或函数做用域中删除用var声明的任何属性。(由于使用var声明的)
  • delete不能删除全局函数, 能够删除对象中的函数
  • 使用const和let声明的任何变量都不能经过delete删除
  • 没法删除不可配置的属性。包括内置对象(如Math、Array、Object)的属性,以及使用Object. defineproperty()等方法建立的不可配置的属性。
  • 严格模式和非严格模式的区别
    • 非严格模式,delete删除configurable为false和不能删除的返回false
    • 严格模式,delete删除configurable为false和不能删除的直接报错

非严格模式code

function Employee() { 
  delete salary;
  var salary;
}
Employee();
复制代码

严格模式删除函数、configurable为false的都会报错cdn

"use strict";
function Employee() {
  delete salary;  // SyntaxError 报错
  var salary;        
}
// Similarly, any direct access to a function
// with delete will raise a SyntaxError
function DemoFunction() {
  //some code
}
delete DemoFunction; // SyntaxError
复制代码

一些场景

// Creates the property adminName on the global scope.
adminName = 'xyz';            

// Creates the property empCount on the global scope.
// Since we are using var, this is marked as non-configurable. The same is true of let and const.
var empCount = 43;

EmployeeDetails = {
  name: 'xyz',
  age: 5,
  designation: 'Developer'
};

// adminName is a property of the global scope.
// It can be deleted since it is created without var,
// and is therefore configurable.
delete adminName;       // returns true

// On the contrary, empCount is not configurable
// since var was used.
delete empCount;       // returns false 

// delete can be used to remove properties from objects.
delete EmployeeDetails.name; // returns true 

// Even when the property does not exist, delete returns "true".
delete EmployeeDetails.salary; // returns true 

// delete does not affect built-in static properties.
delete Math.PI; // returns false 

// EmployeeDetails is a property of the global scope.
// Since it was defined without "var", it is marked configurable.
delete EmployeeDetails;   // returns true

function f() {
  var z = 44;

  // delete doesn't affect local variable names delete z; // returns false } 复制代码

删除原型链上的属性(注意直接删除实例的属性,并不会影响原型的属性)

function Foo() {
  this.bar = 10;
}

Foo.prototype.bar = 42;

var foo = new Foo();

// foo.bar is associated with the 
// own property. 
console.log(foo.bar); // 10 

// Delete the own property within the 
// foo object. 
delete foo.bar; // returns true 

// foo.bar is still available in the 
// prototype chain. 
console.log(foo.bar); // 42 

// Delete the property on the prototype.
delete Foo.prototype.bar; // returns true 

// The "bar" property can no longer be 
// inherited from Foo since it has been 
// deleted. 
console.log(foo.bar); // undefined
复制代码

删除数组的元素

经过delete能够产生 稀疏数组

var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3]; // 这里至关于把trees变成了稀疏数组,why ? 由于 数组是类对象,本质上是key-value的集合,元素个数是4个,而数组的长度是5
if (3 in trees) {
    // this is not executed
}
trees.length // 5
复制代码

关于delete怪异的地方

固然虽然没有违背原则,可是总以为怪怪的

image.png

参考

相关文章
相关标签/搜索