如何引用JavaScript、变量、数据类型 - ReginaF1221/JavaScript_notes GitHub Wiki

如何引用JavaScript、变量、数据类型

HTML控制页面的内容CSS控制页面的样式JavaScript控制页面的行为

一、如何引用JavaScript

内部引用

通过HTML文档内的script标签加载JavaScript代码。

示例:

<script type="text/javascript">
  document.write("Hello World!");
</script>

通过此方式就可以在当前页面中引入script标签中的JavaScript代码。

外部引用

也是使用HTML文档的script标签,但是要使用script标签的src属性,指向外部JavaScript文件的路径。

示例:

<script src="./main.js" />

由于HTML文档是由上向下对页面元素进行解析的,所以在一个HTML文档中,所有的<script>元素都会按照它们在页面中出现的顺序依次被解析,默认情况下,只有在解析完前面的<script>元素中的代码之后,才会开始解析后面的<script>元素中的代码,所以为防止网页加载缓慢,也可以把非关键的JavaScript放到网页最后,即主要内容后面,</body>元素的前面。

示例:

// other code ...    
    <script type="text/javascript" src="./main.js"></script>
  </body>
</html>

使用内部引用的方法在HTML中嵌入JavaScript代码虽然没有问题,但一般认为最好的做法还是尽可能使用外部文件来包含JavaScript代码。不过,并不存在必须使用外部文件的硬性规定,但支持使用外部文件的人多会强调如下优点

  1. 可维护性:遍及不同HTML页面的JavaScript会造成维护问题。但把所有JavaScript文件都放在一个文件夹中,维护起来就轻松多了。而且开发人员因此也能够在不触及HTML标签的情况下,集中精力编辑JavaScript代码。

  2. 可缓存:浏览器能够根据具体的设置缓存链接的所有外部JavaScript文件。也就是说,如果有两个页面都使用同一个文件,那么这个文件只需下载一次。因此,最终结果就是能够加快页面加载的速度

  3. 适应未来:统一定义JavaScript代码,方便查看,同时使代码更安全,可以压缩,也可以加密某个JavaScript文件。

    二、变量

简单来说,变量就是存储信息的容器

变量在使用前通常有两个步骤:声明(指定变量名)和初始化(将信息放在这个变量中)。

在JavaScript中,变量是松散类型的,所谓松散类型就是可以用变量来保存任何类型的数据。换句话说,每个变量仅仅是一个用户保存值的占位符而已。

在JavaScript中定义变量使用var来声明一个变量,后面跟一个变量名,变量名必须是合法的标识符,包含:大小写字母,数组,下划线‘_’,美元符号‘$’,但不能以数字开头。

我们也可以像下面这样来声明一个变量:

var information;

这行代码定义了一个名为information的变量,该变量可以用来存储任何值(像这样未经过初始化的变量,会被保存一个特殊的值——undefined)。

在JavaScript中当一个变量已经被声明和初始化之后,还可以对该变量的值进行修改,如下:

var name = 'Bob';
name = 'Mike';

可以看到在上述代码中的第二行将姓名改为’Mike‘。之前我们提到JavaScript是松散类型的,我们是否可以向下面这样修改变量呢?

var name = 'Bob';
name = 10; // 有效!但不推荐

同时定义多个变量,比如要一起定义姓名,年龄,学号,我们可以用下面的方法来定义变量:

var name = 'Bob';
var age = 16;
var stuNo = 0012323;

// 也可以这样定义
var name = 'Bob',
    age = 16,
    stuNo = 0012323;

第一种方法我们分别定义了三个变量,通过对比上面两种方法可以发现第二种方法将分号改为逗号,只有一个var同时定义了三个变量。同样,由于JavaScript是松散类型的,因而使用不同类型初始化变量的操作可以放在一条语句中来完成。虽然代码里的换行和变量缩进不是必须的,但这样做可以提高代码的可读性。

Variable declarations, wherever they occur, are processed before any code is executed. The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global. If you re-declare a JavaScript variable, it will not lose its value.Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed. (变量声明,无论它们出现在何处,都会在任何代码执行之前处理。 用var声明的变量的范围是其当前的执行上下文,它是封闭函数,或者对于在任何函数外部声明的变量,全局函数。 如果您重新声明了JavaScript变量,它将不会丢失其值。将值赋给未声明的变量会在执行赋值时隐式地将其创建为全局变量(它将成为全局对象的属性)。 )

The differences between declared and undeclared variables are:

  1. Declared variables are constrained in the execution context in which they are declared. Undeclared variables are always global.(声明的变量在声明它们的执行上下文中受到约束。 未声明的变量总是全球性的。)
function x() {
  y = 1;   // Throws a ReferenceError in strict mode
  var z = 2;
}

x();

console.log(y); // logs "1" 
console.log(z); // Throws a ReferenceError: z is not defined outside(引发ReferenceError:z不在外部定义) x
  1. Declared variables are created before any code is executed. Undeclared variables do not exist until the code assigning to them is executed.(声明的变量是在任何代码执行之前创建的。 直到分配给它们的代码被执行,未声明的变量才会存在。)
console.log(a);                // Throws a ReferenceError.
console.log('still going...'); // Never executes.
var a;
console.log(a);                // logs "undefined" or "" depending on browser.
console.log('still going...'); // logs "still going...".
  1. Declared variables are a non-configurable property of their execution context (function or global). Undeclared variables are configurable (e.g. can be deleted).(声明的变量是其执行上下文(函数或全局)的不可配置属性。 未声明的变量是可配置的(例如可以被删除)。)
var a = 1;
b = 2;

delete this.a; // Throws a TypeError in strict mode. Fails silently otherwise.
delete this.b;

console.log(a, b); // Throws a ReferenceError. 
// The 'b' property was deleted and no longer exists.

Because of these three differences, failure to declare variables will very likely lead to unexpected results. Thus it is recommended to always declare variables, regardless of whether they are in a function or global scope. And in ECMAScript 5 strict mode, assigning to an undeclared variable throws an error.(由于这三个区别,未能声明变量很可能会导致意想不到的结果。 因此,建议始终声明变量,而不管它们是处于函数还是全局范围内。 在ECMAScript 5严格模式下,分配给未声明的变量会引发错误。)

Difference between Declaration, Initialization and Assignment(声明,初始化和赋值之间的区别)

lifecycle of a variable(变量的生命周期):

量生命周

  1. Declaration: The variable is registered using a given name within the corresponding scope (explained below – e.g. inside a function).

  2. Initialization: When you declare a variable it is automatically initialized, which means memory is allocated for the variable by the JavaScript engine.

  3. Assignment: This is when a specific value is assigned to the variable.

    Declaration Types声明类型

    Note: while varhas been available in JavaScript since its initial releast, letand const are only available in ES6 (ES2015) and up. See this page for browser compatibility.

    var

    This declaration is probably the most popular, as there was no alternative until ECMAScript 6. Variables declared with var are available in the scope of the enclosing function. If there is no enclosing function, they are available globally.

    Example:

    function sayHello(){
      var hello = "Hello World";
      return hello;
    }
    console.log(hello);
    

    This will cause an error ReferenceError: hello is not defined, as the variable hello is only available within the function sayHello. But the following will work, as the variable will be declared globally – in the same scope console.log(hello) is located:

    var hello = "Hello World";
    function sayHello(){
      return hello;
    }
    console.log(hello);
    
let

let is the descendant of var in modern JavaScript. Its scope is not only limited to the enclosing function, but also to its enclosing block statement. A block statement is everything inside { and }, (e.g. an if condition or loop). The benefit of let is it reduces the possibility of errors, as variables are only available within a smaller scope.

Example:

var name = "Peter";
if(name === "Peter"){
  let hello = "Hello Peter";
} else {
  let hello = "Hi";
}
console.log(hello);

This will cause an error ReferenceError: hello is not defined as hello is only available inside the enclosing block – in this case the if condition. But the following will work:

var name = "Peter";
if(name === "Peter"){
  let hello = "Hello Peter";
  console.log(hello);
} else {
  let hello = "Hi";
  console.log(hello);
}
const常量

Syntax语法:

const x = "Hello World";

Technically a constant isn’t a variable. The particularity of a constant is that you need to assign a value when declaring it and there is no way to reassign it. A const is limited to the scope of the enclosing block, like let.

Constants should be used whenever a value must not change during the applications running time, as you’ll be notified by an error when trying to overwrite them.

Accidental Global Creation(意外的全局变量)

You can write all of above named declarations in the global context (i.e. outside of any function), but even within a function, if you forget to write var, let or const before an assignment, the variable will automatically be global.

Example:

function sayHello(){
  hello = "Hello World";
  return hello;
}
sayHello();
console.log(hello);

The above will output Hello World to the console, as there is no declaration before the assignment hello = and therefore the variable is globally available.

Note: To avoid accidentally declaring global variables you can use strict mode.

Hoisting and the Temporal Dead Zone

Another difference between var and let/const relates to variable hoisting. A variable declaration will always internally be hoisted (moved) to the top of the current scope. This means the following:

console.log(hello);
var hello;
hello = "I'm a variable";

is equivalent to:

var hello;
console.log(hello);
hello = "I'm a variable";

An indication of this behavior is that both examples will log undefined to the console. If var hello; wouldn’t always be on the top it would throw a ReferenceError.

This behavior called hoisting applies to var and also to let/const. As mentioned above, accessing a var variable before its declaration will return undefined as this is the value JavaScript assigns when initializing it.

But accessing a let/const variable before its declaration will throw an error. This is due to the fact that they aren’t accessible before their declaration in the code. The period between entering the variable’s scope and reaching their declaration is called the Temporal Dead Zone – i.e. the period in which the variable isn’t accessible.

You can read more about hoisting in the article Demystifying JavaScript Variable Scope and Hoisting.

Conclusion

To reduce susceptibility to errors you should use const and let whenever possible. If you really need to use var then be sure to move declarations to the top of the scope, as this avoids unwanted behavior related to hoisting.

参考原文、学习资料:

TWS-第三期训练营

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

https://www.sitepoint.com/how-to-declare-variables-javascript/

三、数据类型

JavaScript 是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。这也意味着可以使用同一个变量保存不同类型的数据:

var foo = 42;    // foo is a Number now
var foo = "bar"; // foo is a String now
var foo = true;  // foo is a Boolean now

最新的JavaScript标准定义了 7 种数据类型,它们分别是:

  • 6种原始类型及原始值 (primitive values ):

    在JavaScript中除 Object 以外的所有类型都是不可变的(值本身无法被改变),我们称这些类型的值为“原始值”。

    • Boolean 布尔表示一个逻辑实体,意为真、假,可以有两个值:truefalse

    • Null Null 类型只有一个值:null,表示空值,表示没有被呈现。

    • Undefined 一个没有被赋值的变量会有个默认值undefined

    • Number

      在JavaScript里,数字类型能够代表的范围是**(-(2的63次方-1) ~ (2的63次方-1)**。除了具体的数值,在JavaScript中还有一些带符号的值:+Infinity-InfinityNaN(非数值,Not-a-Number),分别代表正无穷、负无穷和非数值。例如:

      19 / +0; // Infinity
      19 / -0; // -Infinity
      
    • String

      JavaScript的字符串类型用于表示文本数据。在字符串中的每个元素占据了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数量。

      在JavaScript中的字符串需要使用单引号'**'或双引号"**"括起来,表示该值是一个字符串。

      JavaScript 字符串是不可更改的。这意味着字符串一旦被创建,就不能被修改。但是,可以基于对原始字符串的操作来创建新的字符串。例如:

      1. 获取一个字符串的子串可通过选择个别字母或者使用String.substr()
      2. 两个字符串的连接使用连接操作符 (+) 或者String.concat()
    • Symbol(在ES6中新定义,本节暂不讲解)

      符号类型:Symbol 符号(Symbols)是ES6新定义的。符号类型是唯一的并且是不可修改的。Symbol不作为pre-course的学习重点。

  • 对象(Object)类型

    在计算机科学中, 对象是指内存中的可以被 标识符引用的一块区域.

javascript 中的对象(物体),和其它编程语言中的对象一样,可以比照现实生活中的对象(物体)来理解它。 javascript 中对象(物体)的概念可以比照着现实生活中实实在在的物体来理解。

在javascript中,一个对象可以是一个单独的拥有属性和类型的实体。我们拿它和一个杯子做下类比。一个杯子是一个对象(物体),拥有属性。杯子有颜色,图案,重量,由什么材质构成等等。同样,javascript对象也有属性来定义它的特征。

对象可以通过new操作符后跟要创建的对象类型的名称来创建。而创建Object类型的示例并为其添加属性和(或)方法,就可以创建自定义对象,如下所示:

var o = new Object();

我们也可以通过下面的方式直接创建一个对象:

var person = {
  name: 'Bob',
  age: 20,
  gender: 'male'
};

上述对象就定义了一个名为’Bob‘,20岁,的男生。

typeof操作符

由于JavaScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof就是负责提供这方面信息的操作符。对一个值使用typeof操作符可能返回下列某个字符串:

  • 'undefined' —— 未定义
  • 'boolean' —— 布尔值
  • 'string' —— 字符串
  • 'number' —— 数字值
  • 'object' —— 对象或null
  • function —— 函数 下面展示一下使用typeof的示例:
var message = 'some string';
alert(typeof message); // "string"
alert(typeof(message)); // "string"
alert(typeof 95); // number

在实际编程的过程中,可以用typeof判断任何一个变量的数据类型。

对象属性扩展:

属性

在 Javascript 里,对象可以被看作是一组属性的集合。用对象字面量语法来定义一个对象时,会自动初始化一组属性。(也就是说,你定义一个var a = "Hello",那么a本身就会有a.substring这个方法,以及a.length这个属性,以及其它;如果你定义了一个对象,var a = {},那么a就会自动有a.hasOwnProperty及a.constructor等属性和方法。)而后,这些属性还可以被增减。属性的值可以是任意类型,包括具有复杂数据结构的对象。属性使用键来标识,它的键值可以是一个字符串或者符号值(Symbol)。

ECMAScript定义的对象中有两种属性:数据属性和访问器属性。

数据属性

数据属性是键值对,并且每个数据属性拥有下列特性:

数据属性的特性(Attributes of a data property)

特性 数据类型 描述 默认值
Value 任何Javascript类型 包含这个属性的数据值。 undefined
Writable Boolean 如果该值为 false,则该属性的 Value 特性 不能被改变。 true
Enumerable Boolean 如果该值为 true,则该属性可以用 for...in 循环来枚举。 true
Configurable Boolean 如果该值为 false,则该属性不能被删除,并且 除了 ValueWritable 以外的特性都不能被改变。 true
属性 类型 描述
Read-only Boolean ES5 Writable 属性的反状态(Reversed state)
DontEnum Boolean ES5 Enumerable 属性的反状态
DontDelete Boolean ES5 Configurable 属性的反状态

访问器属性

访问器属性有一个或两个访问器函数 (get 和 set) 来存取数值,并且有以下特性:

特性 类型 描述 默认值
Get 函数对象或者 undefined 该函数使用一个空的参数列表,能够在有权访问的情况下读取属性值。另见 get。 undefined
Set 函数对象或者 undefined 该函数有一个参数,用来写入属性值,另见 set。 undefined
Enumerable Boolean 如果该值为 true,则该属性可以用 for...in 循环来枚举。 true
Configurable Boolean 如果该值为 false,则该属性不能被删除,并且不能被转变成一个数据属性。 true

注意:这些特性只有 JavaScript 引擎才用到,因此你不能直接访问它们。所以特性被放在两对方括号中,而不是一对。

"标准的" 对象, 和函数

一个 Javascript 对象就是键和值之间的映射.。键是一个字符串(或者 Symbol) ,值可以是任意类型的值。 这使得对象非常符合 哈希表

函数是一个附带可被调用功能的常规对象。

日期

当你想要显示日期时,毋庸置疑,使用内建的 Date 对象。

有序集: 数组和类型数组

数组是一种使用整数作为键(integer-key-ed)属性和长度(length)属性之间关联的常规对象。此外,数组对象还继承了 Array.prototype 的一些操作数组的便捷方法。例如, indexOf (搜索数组中的一个值) or push (向数组中添加一个元素),等等。 这使得数组是表示列表或集合的最优选择。

参考原文、学习资料:

TWS-第三期训练营

⚠️ **GitHub.com Fallback** ⚠️