今天,在JavaScript手册的翻译的第三部分中,我们将讨论声明变量的不同方法,数据类型,表达式以及使用对象的功能。
→
第1部分:第一个程序,语言功能,标准→
第2部分:代码样式和程序结构→
第3部分:变量,数据类型,表达式,对象→
第4部分:功能→
第5部分:数组和循环→
第6部分:异常,分号,通配符文字→
第7部分:严格模式,此关键字,事件,模块,数学计算→
第8部分:ES6功能概述→
第9部分:ES7,ES8和ES9标准概述
变数
变量是分配了值的标识符。 可以在程序中访问变量,以这种方式使用为其分配的值。
JavaScript本身的变量不包含有关将存储在其中的值类型的信息。 这意味着通过写入变量(例如字符串),以后可以在其中写入数字。 这样的操作不会引起程序错误。 因此,JavaScript有时被称为“非类型化”语言。
在使用变量之前,必须使用
var
或
let
关键字对其进行声明。 当涉及常量时,将使用
const
关键字。 在不使用这些关键字的情况下,可以声明变量并为其分配一个特定值,但是不建议这样做。
▍关键字var
在ES2015标准之前,使用
var
关键字是声明变量的唯一方法。
var a = 0
如果在此构造中省略
var
,则该值将分配给未声明的变量。 该操作的结果取决于程序运行的模式。
因此,如果启用了所谓的严格模式,则将导致错误。 如果未启用严格模式,则将发生隐式变量声明,并将其分配给全局对象。 特别是,这意味着即使在函数完成工作后,在某个函数中以这种方式隐式声明的变量也将可用。 通常,期望函数中声明的变量不会“超出”其限制。 看起来像这样:
function notVar() { bNotVar = 1 // } notVar() console.log(bNotVar)
它会
1
控制台上得到
1
,通常没有人期望程序会出现这种行为,表达式
bNotVar = 1
看起来并不像尝试声明和初始化变量,而是试图访问在函数外部
bNotVar = 1
的变量(这是很正常的)。 结果,变量的隐式声明会使读取代码的人感到困惑,并可能导致程序异常。 稍后我们将讨论功能和范围,现在,当表达式的含义是声明变量时,请始终尝试使用专用关键字。 如果在此示例中,函数主体被重写为
var bNotVar = 1
,则尝试启动上述代码片段将导致错误消息(可以在浏览器控制台中看到)。
例如,它可能看起来像这样:
Uncaught ReferenceError: bNotVar is not defined
。 其含义可以归结为以下事实:程序无法使用不存在的变量运行。 初次启动程序时,看到这样的错误消息比编写无法理解的,可能表现异常的代码要好得多。
如果在声明变量时未对其进行初始化,未为其分配任何值,则将自动为其分配
undefined
的值。
var a //typeof a === 'undefined'
通过使用
var
关键字声明的变量可以通过为它们分配新的值来重复声明(但这会使读取代码的人感到困惑)。
var a = 1 var a = 2
您可以在一个表达式中声明几个变量:
var a = 1, b = 2
变量的范围称为程序的范围,在该程序中可以访问(可见)此变量。
使用函数外部的
var
关键字初始化的变量分配给全局对象。 它具有全局范围,可从程序中的任何位置访问。 如果使用函数内部的
var
关键字声明了变量,则该变量仅在该函数内部可见,是该函数的局部变量。
如果在使用
var
的函数中声明了变量,且其名称与全局范围内某个变量的名称匹配,则它将“覆盖”全局变量。 也就是说,在函数内部访问此类变量时,它将使用其本地版本。
重要的是要理解,块(用大括号括起来的代码区域)不会创建新的可见性区域。 调用函数时会创建一个新的作用域。
var
关键字具有所谓的功能范围,而不是功能块。
如果在功能代码中声明了变量,则整个功能代码都可以看到该变量。 即使在函数代码的末尾用
var
声明了变量,您也可以在代码的开头引用它,因为引发变量(提升)的机制在JavaScript中起作用。 该机制“提高”变量声明,但不提高其初始化操作。 这可能会引起混乱,因此将其作为在函数开始时声明变量的规则。
let关键字let
let关键字出现在ES2015中,可以简化为
var
的“块”版本。 使用
let
关键字声明的变量的范围仅限于声明了它的块,运算符或表达式以及嵌套块。
如果“ let”一词本身看起来不太清楚,则可以想象使用了“ let”一词。 然后,可以将表达式
let color = 'red'
转换为英语:“让颜色为红色”,并转换为俄语:“使颜色为红色”。
通过使用
let
关键字,您可以消除与
var
关键字相关联的歧义(例如,您不能使用
let
两次声明相同的变量)。 例如,在初始化循环时,在函数外部使用
let
不会创建全局变量。
例如,这样的代码将导致错误:
for (let i = 0; i < 5; i++) { console.log(i) } console.log(i)
如果在初始化循环时使用计数器
var
声明计数器
i
,则在完成循环后,
i
将在循环外部可用。
如今,在基于现代标准开发JS程序时,您可以完全放弃
var
而仅使用
let
和
const
关键字。
▍关键字const
使用
var
或
let
关键字声明的变量可以被覆盖。 如果使用
const
代替这些关键字,则不能为通过常量帮助声明和初始化的常量分配新值。
const a = 'test'
在此示例中,不能为常数
a
分配新值。 但应注意,如果
a
不是原始值(例如数字),而是对象,则使用
const
关键字不会保护该对象不受更改。
当他们说将对象写入变量时,实际上是指变量引用该对象。 此链接无法更改,并且链接可以指向的对象也可以更改。
const
关键字不会使对象不可变。 它只是防止以相应的常量编写的对其引用的更改。 看起来是这样的:
const obj = {} console.log(obj.a) obj.a = 1 // console.log(obj.a) //obj = 5 //
在
obj
常量中,初始化后会写入一个新的空对象。 尝试访问其不存在的属性
a
不会导致错误。 控制台变得
undefined
。 之后,我们向对象添加一个新属性,然后再次尝试访问它。 这次,此属性的值
1
进入控制台。 如果取消注释示例的最后一行,则尝试执行此代码将导致错误。
const
关键字与
let
非常相似,尤其是它具有块作用域。
在现代条件下,完全可以接受使用
const
关键字,仅在特殊情况下才允许使用,声明其值不打算更改的所有实体。 怎么了 事实是,最好努力使用最简单的可用结构,以免使程序复杂化并避免错误。
资料类型
JavaScript有时被称为“非类型化”语言,但事实并非如此。 确实可以将不同类型的值写入变量,但是JavaScript中还是有数据类型。 特别是,我们正在谈论原始和对象数据类型。
为了确定某个值的数据类型,可以使用
typeof
运算符。 它返回一个指示操作数类型的字符串。
▍原始数据类型
以下是原始JavaScript数据类型的列表:
number
string
(字符串)boolean
(布尔值)null
(特殊null
值)undefined
(特殊值undefined
)symbol
(在特殊情况下使用的符号,出现在ES6中)
此处,数据类型的名称以
typeof
运算符返回它们的形式给出。
让我们讨论一下此列表中最常用的数据类型。
类型编号
JavaScript中
number
类型的值表示为64位双精度浮点数。
在代码中,数字文字在十进制系统中表示为整数和小数。 您可以使用其他方法来记录数字。 例如,如果在数字文字的开头有前缀
0x
它被视为以十六进制表示的数字。 数字也可以用指数符号表示(在这种数字中,您可以找到字母
e
)。
以下是整数条目的示例:
10 5354576767321 0xCC //
这是分数。
3.14 .1234 5.2e4 //5.2 * 10^4
数值文字(此行为也是某些其他原始类型的特征),当您尝试将它们作为对象访问时,在操作期间会自动将其转换为相应的对象,这些对象称为“对象包装器”。 在这种情况下,我们正在谈论对象包装器
Number
。
例如,此处看起来像是尝试访问变量
a
,其中在谷歌浏览器控制台中将数字文字作为对象写入其中。
数字对象换行工具提示例如,如果您使用
Number
类型的对象的
toString()
方法,它将返回数字的字符串表示形式。 看起来像可以在浏览器控制台(以及常规代码)中执行的相应命令,如下所示:
a.toString()
注意方法名称后面的双括号。 如果您不放置它们,则系统不会给出错误,但是,控制台将显示一些与数字5完全不同的东西,而不是预期的输出。
全局
Number
对象可以以构造函数的形式使用,可以在其帮助下创建新的数字(尽管这种形式几乎从未使用过),也可以将其用作独立实体,而无需创建它的实例(即,一些数字表示)帮助)。 例如,其
Number.MAX_VALUE
属性包含可以用JavaScript表示的最大数值。
类型字符串
string
类型的值是
string
序列。 这些值被指定为用单引号或双引号引起来的字符串文字。
'A string' "Another string"
可以使用反斜杠字符将字符串值分为几部分。
"A \ string"
字符串可能包含所谓的转义序列,当将字符串打印到控制台时会对其进行解释。 例如,序列
\n
表示换行符。 反斜杠字符还可以用于将引号添加到包含在同一引号中的字符串。 用
\
转义引号字符会导致系统无法将其视为特殊字符。
'I\'ma developer'
可以使用
+
运算符来连接字符串。
"A " + "string"
模板文字
ES2015引入了所谓的模式文字或模式字符串。 它们是用反引号(
`
)括起来的字符串,并具有一些有趣的属性。
`a string`
例如,在模板文字中,您可以替换某些值,这些值是评估JavaScript表达式的结果。
`a string with ${something}` `a string with ${something+somethingElse}` `a string with ${obj.something()}`
使用反引号使编写多行字符串文字变得容易:
`a string with ${something}`
布尔型
JavaScript有两个使用布尔值的保留字-分别为
true
(true)和
false
(false)。 比较运算(例如
==
,
===
,
<
,
>
)返回
true
或
false
。
逻辑表达式用于
if
和
while
等构造中,有助于控制程序的进度。
应该注意的是,在期望为
true
或
false
情况下,您可以使用语言自动将其视为真(真)或假(假)的其他值。
特别是,以下是错误值:
0 -0 NaN undefined null '' //
其余值为true。
输入空值
JavaScript具有一个特殊的
null
值,该值指示不存在值。 其他语言也使用类似的含义。
类型未定义
写入某个变量的
undefined
值表示该变量未初始化,并且没有任何值。
该值是从没有使用
return
关键字显式返回结果的函数中自动返回的。 如果函数接受未指定的参数,则在调用该参数时未将其设置为
undefined
。
为了检查
undefined
的值,可以使用以下构造。
typeof variable === 'undefined'
▍物件
所有不是基本值的值都具有对象类型。 我们在谈论函数,数组,所谓的“对象”以及许多其他实体。 所有这些数据类型都是基于
object
类型的,尽管它们在很多方面都存在差异,但是它们有很多共同点。
表达方式
表达式是代码片段,可以根据执行的计算将特定值处理并获得。 JavaScript有几种类别的表达式。
算术表达式
计算结果为数字的表达式属于此类别。
1 / 2 i++ i -= 2 i * 2
字符串表达式
计算此类表达式的结果是字符串。
'A ' + 'string' 'A ' += 'string'
主要表达
文字,常量和对标识符的引用都属于此类。
2 0.02 'something' true false this // , undefined i // i
这还包括JavaScript的一些关键字和构造。
function class function* // yield // / yield* // async function* // await // /pattern/i // () //
数组和对象初始化表达式
[] // {} // [1,2,3] {a: 1, b: 2} {a: {b: 1}}
逻辑表达式
在逻辑表达式中,使用逻辑运算符,其计算结果为逻辑值。
a && b a || b !a
属性访问表达式
这些表达式使您可以访问对象的属性和方法。
object.property // ( ) object[property] object['property']
对象创建表达式
new object() new a(1) new MyRectangle('name', 2, {a: 4})
函数声明表达式
function() {} function(a, b) { return a * b } (a, b) => a * b a => a * 2 () => { return 2 }
呼叫表达
这样的表达式用于调用对象的函数或方法。
ax(2) window.resize()
处理对象
上面我们已经遇到对象,谈论对象文字,调用它们的方法,访问它们的属性。 在这里,我们更详细地讨论对象,尤其是考虑原型继承机制和
class
关键字的使用。
▍原型继承
JavaScript在现代编程语言中脱颖而出,因为它支持原型继承。 大多数面向对象的语言都使用基于类的继承模型。
每个JavaScript对象都有一个特殊的属性(
__proto__
),该属性指向其原型的另一个对象。 一个对象继承了原型的属性和方法。
假设我们有一个使用对象文字创建的对象。
const car = {}
或者我们使用
Object
构造函数创建了一个对象。
const car = new Object()
在上述任何一种情况下,
car
对象的原型都是
Object.prototype
。
如果创建也是对象的数组,则其原型为
Array.prototype
对象。
const list = [] // const list = new Array()
您可以如下验证。
car.__proto__ == Object.prototype //true car.__proto__ == new Object().__proto__ //true list.__proto__ == Object.prototype //false list.__proto__ == Array.prototype //true list.__proto__ == new Array().__proto__ //true
在这里,我们使用了
__proto__
属性,开发人员不必使用它,但是您通常可以访问它。 应该注意的是,获取对象原型的一种更可靠的方法是使用全局
Object
的
getPrototypeOf()
方法。
Object.getPrototypeOf(new Object())
具有该原型的对象可以访问该原型的所有属性和方法。 例如,在这里看起来像他们的数组列表。
数组提示所有对象的基本原型是
Object.prototype
。
Array.prototype.__proto__ == Object.prototype
Object.prototype
原型。
我们上面看到的是原型链的示例。
尝试访问对象的属性或方法时,如果对象本身不具有此类属性或方法,则在其原型中搜索对象,然后在原型原型中进行搜索,依此类推,直到找到所需的对象或直到原型链不会结束。
除了使用
new
运算符以及使用对象常量或数组常量创建对象之外,还可以使用
Object.create()
方法创建对象的实例。 传递给此方法的第一个参数是一个对象,它将成为使用该方法创建的对象的原型。
const car = Object.create(Object.prototype)
您可以使用
isPrototypeOf()
方法检查某个对象是否是另一个对象的原型链的一部分。
const list = [] Array.prototype.isPrototypeOf(list)
构造函数
上面,我们使用该语言中已经可用的构造函数创建了新对象(调用它们时,将使用
new
关键字)。 . .
function Person(name) { this.name = name } Person.prototype.hello = function() { console.log(this.name) } let person = new Person('Flavio') person.hello() console.log(Person.prototype.isPrototypeOf(person))
-. ,
this
.
name
, . . - ,
name
, .
,
name
, . , , ,
hello()
. ,
Person
hello()
( ).
▍
ES6 JavaScript «».
JavaScript . , JS . , , , « » . , , , , , .
.
class Person { constructor(name) { this.name = name } hello() { return 'Hello, I am ' + this.name + '.' } }
,
new ClassIdentifier()
.
constructor
, .
.
hello()
— , , .
Person
.
const flavio = new Person('Flavio') flavio.hello()
,
. , , , , .
, ( ) , , -, .
class Programmer extends Person { hello() { return super.hello() + ' I am a programmer.' } } const flavio = new Programmer('Flavio') flavio.hello()
hello()
Hello, I am Flavio. I am a programmer
.
(), .
super
.
, , , , , . (
static
) , .
JavaScript , (, ) . , , .
,
get
set
. — , , . -, — .
class Person { constructor(name) { this.userName = name } set name(value) { this.userName = value } get name() { return this.userName } }
总结
, , JavaScript. .
亲爱的读者们! JS, , class.
