JavaScripe学习(1)


JavaScript 教程

基本语法

1. 语句

var声明变量

var a = 1 + 3;

ECMAScript2015的最好的特性之一是使用const和let声明变量。这些声明是块级作用域(与旧的函数作用域的var相反),并且在声明语句前,变量都处于临时死区,这是一个很大的进步。

2.2 变量提升

console.log(a);
var a = 1;
//不会报错,但是也不会显示1。实际上运行下面的代码
var a;
console.log(a);
a = 1;

3 标识符

第二个字符可以用数字,第一个不可以。下划线可以用在第一个。中文是合法字符。

5 区块

{var a = 1;
a = 2}
console.log(a)

输出:

2

JavaScript 使用大括号,将多个相关的语句组合在一起,称为“区块”(block)。
对于var命令来说,JavaScript 的区块不构成单独的作用域(scope)。

6.1 严格相等运算符(===)和相等运算符(==

简单说,它们的区别是相等运算符(==)比较两个值是否相等,严格相等运算符(===)比较它们是否为“同一个值”。
如果两个值不是同一类型,严格相等运算符(===)直接返回false,而相等运算符(==)会将它们转换成同一个类型,再用严格相等运算符进行比较。

6.4 三元运算符

语句如下:
(条件) ? 表达式1 : 表达式2
条件为true,则执行表达式1;条件为false,执行表达式2

var even = (n % 2 === 0) ? true : false;
//等效于
var even;
if (n % 2 === 0) {
  even = true;
} else {
  even = false;
}

//可用于:
var myVar;
console.log(
  myVar ?
  'myVar has a value' :
  'myVar does not have a value'
)

7.5 标签(label)

JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。
标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。
标签通常与break语句和continue语句配合使用,跳出特定的循环。

下面代码为一个双重循环区块,break命令后面加上了top标签(注意,top不用加引号),满足条件时,直接跳出双层循环。如果break语句后面不使用标签,则只能跳出内层循环,进入下一次的外层循环。
这个是和java一样的,只是我没怎么用。

top:
  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (i === 1 && j === 1) break top;
      console.log('i=' + i + ', j=' + j);
    }
  }
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0

foo: {
  console.log(1);
  break foo;
  console.log('本行不会输出');
}
console.log(2);

//下面代码中,continue命令后面有一个标签名,
//满足条件时,会跳过当前循环,直接进入下一轮外层循环。
//如果continue语句后面不使用标签,则只能进入下一轮的内层循环。
top:
  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (i === 1 && j === 1) continue top;
      console.log('i=' + i + ', j=' + j);
    }
  }

数据类型

简介

数值(number):整数和小数(比如1和3.14)
字符串(string):文本(比如Hello World)。
布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)
undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
null:表示空值,即此处的值为空。
对象(object):各种值组成的集合。

undefined是什么意思?
undefined和null同样代表空值。它们之间是否有明确的不同?
undefined文档

对象object是最复杂的数据类型,又可以分成三个子类型:
狭义的对象(object);数组(array);函数(function
狭义的对象和数组是两种不同的数据组合方式,除非特别声明,本教程的“对象”都特指狭义的对象。函数其实是处理数据的方法,JavaScript 把它当成一种数据类型,可以赋值给变量,这为编程带来了很大的灵活性,也为 JavaScript 的“函数式编程”奠定了基础。

typeof 运算符(数组和对象,null部分感觉很混乱)

JavaScript 有三种方法,可以确定一个值到底是什么类型。

  • typeof运算符
  • instanceof运算符
  • Object.prototype.toString方法

先了解typeof语法

typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"

function f() {}
typeof f
// "function"

//typeof可以用来检查一个没有声明的变量,而不报错。
v
typeof v
// "undefined"

变量v没有用var命令声明,直接使用就会报错。但是,放在typeof后面,就不报错了,而是返回undefined。

// 错误的写法
if (v) {
  // ...
}
// ReferenceError: v is not defined

// 正确的写法
if (typeof v === "undefined") {
  // ...
}

数组,对象
空数组([])的类型也是object,这表示在 JavaScript 内部,数组本质上只是一种特殊的对象。

typeof window // "object"
typeof {} // "object"
typeof [] // "object"

var o = {};
var a = [];

o instanceof Array // false
a instanceof Array // true

null

typeof null // "object"

null, undefined 和布尔值

使用JavaScript中undefined小技巧

布尔值

如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true。
undefinednullfalse0NaN""''(空字符串)
注意,空数组([])和空对象({})对应的布尔值,都是true

数值

JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,1与1.0是相同的,是同一个数。

1 === 1.0 // true

由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。

0.1 + 0.2 === 0.3
// false

0.3 / 0.1
// 2.9999999999999996

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

parseInt方法用于将字符串转为整数。
如果字符串头部有空格,空格会被自动去除。
如果parseInt的参数不是字符串,则会先转为字符串再转换。
字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分。

parseInt('   81') // 81

//如果`parseInt`的参数不是字符串,则会先转为字符串再转换。
parseInt(1.23) // 1
// 等同于
parseInt('1.23') // 1

//字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分。
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15

isFinite方法返回一个布尔值,表示某个值是否为正常的数值。

isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(undefined) // false
isFinite(null) // true
isFinite(-1) // true

字符串

对象

什么是对象?简单说,对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。

var obj = {
  foo: 'Hello',
  bar: 'World'
};

对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。

var obj = {
  p: function (x) {
    return 2 * x;
  }
};

obj.p(1) // 2

如果属性的值还是一个对象,就形成了链式引用。

var o1 = {};
var o2 = { bar: 'hello' };

o1.foo = o2;
o1.foo.bar // "hello"

属性可以动态创建,不必在对象声明时就指定。

var obj = {};
obj.foo = 123;
obj.foo // 123

如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。

var o1 = {};
var o2 = o1;

o1.a = 1;
o2.a // 1

o2.b = 2;
o1.b // 2

表达式还是语句?

{ foo: 123 }

读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。
请注意,如果使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理。

var obj = {
  p: 'Hello World'
};

obj.p // "Hello World"
obj['p'] // "Hello World"

//如果没有引号
var foo = 'bar';
var obj = {
  foo: 1,
  bar: 2
};
obj.foo  // 1
obj[foo]  // 2

数字键可以不加引号,因为会自动转成字符串。
数值键名不能使用点运算符(因为会被当成小数点),只能使用方括号运算符。

var obj = {
  123: 'hello world'
};

obj.123 // 报错
obj[123] // "hello world"

查看一个对象本身的所有属性,可以使用Object.keys方法。

var obj = {
  key1: 1,
  key2: 2
};

Object.keys(obj);
// ['key1', 'key2']

属性的删除命令
注意,删除一个不存在的属性,delete不报错,而且返回true。
有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。

var obj = { p: 1 };
Object.keys(obj) // ["p"]

delete obj.p // true
obj.p // undefined
Object.keys(obj) // []

var obj = {};
delete obj.p // true

属性是否存在:in 运算符。可以是继承的属性。
如果需要看是否是自己的属性,可以用hasOwnProperty方法判断一下,是否为对象自身的属性。

var obj = { p: 1 };
'p' in obj // true
'toString' in obj // true

var obj = {};
if ('toString' in obj) {
  console.log(obj.hasOwnProperty('toString')) // false
}

for…in循环用来遍历一个对象的全部属性。

  1. 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
    (关于对象属性的可遍历性,参见《标准库》章节中 Object 一章的介绍。)
  2. 它不仅遍历对象自身的属性,还遍历继承的属性
    如果继承的属性是可遍历的,那么就会被for…in循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用for…in的时候,应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。
var obj = {a: 1, b: 2, c: 3};
for (var i in obj) {
  console.log('键名:', i);
  console.log('键值:', obj[i]);
}

var obj = {};
// toString 属性是存在的
obj.toString // toString() { [native code] }
for (var p in obj) {
  console.log(p);
} // 没有任何输出

var person = { name: '老张' };
for (var key in person) {
  if (person.hasOwnProperty(key)) {
    console.log(key);
  }
}
// name

with 语句,它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

var obj = {
  p1: 1,
  p2: 2,
};
with (obj) {
  p1 = 4;
  p2 = 5;
}
// 等同于
obj.p1 = 4;
obj.p2 = 5;

// 例二
with (document.links[0]){
  console.log(href);
  console.log(title);
  console.log(style);
}
// 等同于
console.log(document.links[0].href);
console.log(document.links[0].title);
console.log(document.links[0].style);

注意,如果with区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。

函数

函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。
三种函数的声明方式

var v = 1;

function f(){
  var v = 2;
  console.log(v);
}

f() // 2
v // 1

函数参数不是必需的,JavaScript 允许省略参数。

function f(a, b) {
  return a;
}

f(1, 2, 3) // 1
f(1) // 1
f() // undefined

f.length // 2

但是,没有办法只省略靠前的参数,而保留靠后的参数。如果一定要省略靠前的参数,只有显式传入undefined

函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递(passes by value)。这意味着,在函数体内修改参数值,不会影响到函数外部。
但是,如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递(pass by reference)。也就是说,传入函数的原始值的地址,因此在函数内部修改参数,将会影响到原始值。.注意,如果函数内部修改的,不是参数对象的某个属性,而是替换掉整个参数,这时不会影响到原始值。

var obj = { p: 1 };

function f(o) {
  o.p = 2;
}
f(obj);

obj.p // 2

var obj = [1, 2, 3];

function f(o) {
  o = [2, 3, 4];
}
f(obj);

obj // [1, 2, 3]

闭包

function f1() {
  var n = 999;
  function f2() {
    console.log(n);
  }
  return f2;
}

var result = f1();
result(); // 999

数组

length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员会自动减少到length设置的值。
清空数组的一个有效方法,就是将length属性设为0。
如果人为设置length大于当前元素个数,则数组的成员数量会增加到这个值,新增的位置都是空位。
上面代码表示,当length属性设为大于数组个数时,读取新增的位置都会返回undefined。

var arr = [ 'a', 'b', 'c' ];
arr.length // 3

arr.length = 2;
arr // ["a", "b"]

值得注意的是,由于数组本质上是一种对象,所以可以为数组添加属性,但是这不影响length属性的值。

var a = [];

a['p'] = 'abc';
a.length // 0

a[2.1] = 'abc';
a.length // 0

当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位(hole)。
使用delete命令删除一个数组成员,会形成空位,并且不会影响length属性。

var a = [1, , 1];
a.length // 3

var a = [1, 2, 3];
delete a[1];
a[1] // undefined
a.length // 3

算术运算符

2.2 对象的相加
一般来说,对象的valueOf方法总是返回对象自身,这时再自动调用对象的toString方法,将其转为字符串。

var obj = { p: 1 };
obj + 2 // "[object Object]2"

var obj = { p: 1 };
obj.valueOf() // { p: 1 }

var obj = { p: 1 };
obj.valueOf().toString() // "[object Object]"

知道了这个规则以后,就可以自己定义valueOf方法或toString方法,得到想要的结果。

var obj = {
  valueOf: function () {
    return 1;
  }
};

obj + 2 // 3

这里有一个特例,如果运算子是一个Date对象的实例,那么会优先执行toString方法。

var obj = new Date();
obj.valueOf = function () { return 1 };
obj.toString = function () { return 'hello' };

obj + 2 // "hello2"

3 余数运算符(%)返回前一个运算子被后一个运算子除,所得的余数。
需要注意的是,运算结果的正负号由第一个运算子的正负号决定。所以,为了得到负数的正确余数值,可以先使用绝对值函数。
余数运算符还可以用于浮点数的运算。但是,由于浮点数不是精确的值,无法得到完全准确的结果。

-1 % 2 // -1
1 % -2 // 1

// 错误的写法
function isOdd(n) {
  return n % 2 === 1;
}
isOdd(-5) // false
isOdd(-4) // false

// 正确的写法
function isOdd(n) {
  return Math.abs(n % 2) === 1;
}
isOdd(-5) // true
isOdd(-4) // false

6.5 % 2.1
// 0.19999999999999973

4 自增和自减运算符
自增和自减运算符有一个需要注意的地方,就是放在变量之后,会先返回变量操作前的值,再进行自增/自减操作;放在变量之前,会先进行自增/自减操作,再返回变量操作后的值。

var x = 1;
var y = 1;

x++ // 1
++y // 2

5 数值运算符,负数值运算符
数值运算符(+)同样使用加号,但它是一元运算符(只需要一个操作数),而加法运算符是二元运算符(需要两个操作数).数值运算符的作用在于可以将任何值转为数值(与Number函数的作用相同)。

+true // 1
+[] // 0
+{} // NaN

var x = 1;
-x // -1
-(-x) // 1

布尔运算符

3 且运算符(&&)
如果第一个运算子的布尔值为true,则返回第二个运算子的值(注意是值,不是布尔值);如果第一个运算子的布尔值为false,则直接返回第一个运算子的值,且不再对第二个运算子求值。

't' && '' // ""
't' && 'f' // "f"
't' && (1 + 2) // 3
'' && 'f' // ""
'' && '' // ""

var x = 1;
(1 - 1) && ( x += 1) // 0
x // 1

这种跳过第二个运算子的机制,被称为“短路”。有些程序员喜欢用它取代if结构,比如下面是一段if结构的代码,就可以用且运算符改写。

if (i) {
  doSomething();
}

// 等价于

i && doSomething();

二进制位运算符

位运算符只对整数起作用,如果一个运算子不是整数,会自动转为整数后再执行。另外,虽然在 JavaScript内部,数值都是以64位浮点数的形式储存,但是做位运算的时候,是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数。

function toInt32(x) {
  return x | 0;
  
toInt32(1.001) // 1
toInt32(1.999) // 1
toInt32(1) // 1
toInt32(-1) // -1
toInt32(Math.pow(2, 32) + 1) // 1
toInt32(Math.pow(2, 32) - 1) // -1
}

二进制或运算符
位运算只对整数有效,遇到小数时,会将小数部分舍去,只保留整数部分。所以,将一个小数与0进行二进制或运算,等同于对该数去除小数部分,即取整数位。

2.9 | 0 // 2
-2.9 | 0 // -2

二进制与运算符。

0 & 3 // 0

二进制否运算符
二进制否运算符(~)将每个二进制位都变为相反值(0变为1,1变为0)。它的返回结果有时比较难理解,因为涉及到计算机内部的数值表示机制。
3的32位整数形式是00000000000000000000000000000011,二进制否运算以后得到11111111111111111111111111111100。由于第一位(符号位)是1,所以这个数是一个负数。JavaScript 内部采用补码形式表示负数,即需要将这个数减去1,再取一次反,然后加上负号,才能得到这个负数对应的10进制值。这个数减去1等于11111111111111111111111111111011,再取一次反得到00000000000000000000000000000100,再加上负号就是-4。考虑到这样的过程比较麻烦,可以简单记忆成,一个数与自身的取反值相加,等于-1

对字符串进行二进制否运算,JavaScript 引擎会先调用Number函数,将字符串转为数值。
Number函数将字符串转为数值的规则。参见《数据的类型转换》一章。

~ 3 // -4

5 异或运算符
异或运算(^)在两个二进制位不同时返回1,相同时返回0。

“异或运算”有一个特殊运用,连续对两个数a和b进行三次异或运算,a^=b; b^=a; a^=b;,可以互换它们的值。这意味着,使用“异或运算”可以在不引入临时变量的前提下,互换两个变量的值。

//0(二进制00)与3(二进制11)进行异或运算,它们每一个二进制位都不同,所以得到11(即3)。
0 ^ 3 // 3

var a = 10;
var b = 99;

a ^= b, b ^= a, a ^= b;

a // 99
b // 10

6 左移运算符
左移运算符(<<)表示将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2的指定次方。向左移动的时候,最高位的符号位是一起移动的。
(为什么是乘以2呢,左移一位和2进制里乘以10一样呀)

如果左移0位,就相当于将该数值转为32位整数,等同于取整,对于正数和负数都有效。

4 << 1
// 8

-4 << 1
// -8

13.5 << 0
// 13

-13.5 << 0
// -13

7 右移运算符

8 头部补零的右移运算符
头部补零的右移运算符(>>>)与右移运算符(>>)只有一个差别,就是一个数的二进制形式向右移动时,头部一律补零,而不考虑符号位。所以,该运算总是得到正值。对于正数,该运算的结果与右移运算符(>>)完全一致,区别主要在于负数。

9 开关作用
假定某个对象有四个开关,每个开关都是一个变量。那么,可以设置一个四位的二进制数,它的每个位对应一个开关。

var FLAG_A = 1; // 0001
var FLAG_B = 2; // 0010
var FLAG_C = 4; // 0100
var FLAG_D = 8; // 1000

var flags = 5; // 二进制的0101

if (flags & FLAG_C) {
  // ...
}
// 0101 & 0100 => 0100 => true

其他运算符,运算顺序

1 void 运算符
void运算符的作用是执行一个表达式,然后不返回任何值,或者说返回undefined

var x = 3;
void (x = 5) //undefined
x // 5

2 逗号运算符
逗号运算符用于对两个表达式求值,并返回后一个表达式的值。
3 运算顺序

语法专题

数据类型的转换

JavaScript 是一种动态类型语言,变量没有类型限制,可以随时赋予任意值。

虽然变量的数据类型是不确定的,但是各种运算符对数据类型是有要求的。如果运算符发现,运算子的类型与预期不符,就会自动转换类型。比如,减法运算符预期左右两侧的运算子应该是数值,如果不是,就会自动将它们转为数值。

var x = y ? 1 : 'a';

'4' - '3' // 1

强制转换

强制转换主要指使用Number()String()Boolean()三个函数,手动将各种类型的值,分别转换成数字、字符串或者布尔值。

  • Number函数
    Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。
parseInt('42 cats') // 42
Number('42 cats') // NaN

简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。
之所以会这样,是因为Number背后的转换规则比较复杂。

  1. 调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。

  2. 如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。

  3. 如果toString方法返回的是对象,就报错。

对象的valueOf 和 toString方法分别会返回什么啊?
默认情况下,对象的valueOf方法返回对象本身,所以一般总是会调用toString方法,而toString方法返回对象的类型字符串(比如[object Object])。所以,会有下面的结果。

Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5

var obj = {x: 1};
Number(obj) // NaN
// 等同于
if (typeof obj.valueOf() === 'object') {
  Number(obj.toString());
} else {
  Number(obj.valueOf());
}
  • String函数
    String函数可以将任意类型的值转化成字符串
  1. 原始类型值
    数值:转为相应的字符串。
    字符串:转换后还是原来的值。
    布尔值:true转为字符串"true",false转为字符串"false"。
    undefined:转为字符串"undefined"。
    null:转为字符串"null"。
  2. 对象
    String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。
    String方法背后的转换规则,与Number方法基本相同,只是互换了valueOf方法和toString方法的执行顺序。
    1.先调用自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
    2.如果toString方法返回的是对象,再调用原对象的valueOf方法。如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
    3.如果valueOf方法返回的是对象,就报错。

下面代码先调用对象的toString方法,发现返回的是字符串[object Object],就不再调用valueOf方法了。

String({a: 1})
// "[object Object]"

// 等同于
String({a: 1}.toString())
// "[object Object]"
  • Boolean()
    Boolean()函数可以将任意类型的值转为布尔值。
    它的转换规则相对简单:除了以下五个值的转换结果为false,其他的值全部为true。
undefined
null
0(包含-0+0NaN
''(空字符串)
  • 自动转换
    遇到以下三种情况时,JavaScript 会自动转换数据类型,即转换是自动完成的,用户不可见。
123 + 'abc' // "123abc"

if ('abc') {
  console.log('hello')
}  // "hello"

+ {foo: 'bar'} // NaN
- [1, 2, 3] // NaN

错误处理机制

上面代码中,我们调用Error构造函数,生成一个实例对象err。Error构造函数接受一个参数,表示错误提示,可以从实例的message属性读到这个参数。抛出Error实例对象以后,整个程序就中断在发生错误的地方,不再往下执行。

  • 原生错误类型
    提供了七种错误类型

  • 自定义错误
    继承Error对象

function UserError(message) {
  this.message = message || '默认信息';
  this.name = 'UserError';
}

UserError.prototype = new Error();
UserError.prototype.constructor = UserError;

编程风格

console 对象与控制台

在这里插入图片描述

标准库

在这里插入图片描述

Object对象

在这里插入图片描述
JavaScript原生提供的Object对象的原生方法分为两类,Object本身的方法与Object的实例方法

  • Object对象本身的方法
    所谓“本身的方法”就是直接定义在Object对象的方法。
    比如:下面代码中,print方法就是直接定义在Object对象上。
Object.print = function (o) { console.log(o) };
  • Object的实例方法
  • 所谓实例方法就是定义在Object原型对象Object.prototype上的方法。它可以被Object实例直接使用。
    关于原型对象object.prototype的详细解释,参见《面向对象编程》章节。这里只要知道,凡是定义在Object.prototype对象上面的属性和方法,将被所有实例对象共享就可以了。
Object.prototype.print = function () {
  console.log(this);
};

var obj = new Object();
obj.print() // Object

属性描述对象

JavaScript 提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”(attributes object)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。

{
  value: 123,
  writable: false,
  enumerable: true,
  configurable: false,
  get: undefined,
  set: undefined
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值