JavaScript的严厉形式和一般形式
“use strict”;
望文生义也就是 JavaScript 会在所谓严厉形式下实行,其一个主要的上风在于能够强迫开发者防止运用未声明的变量。关于老版本的浏览器或许实行引擎则会自动疏忽该指令。
在一般形式中,假如一个变量没有声明就赋值,默许是全局变量。严厉形式制止这类用法,全局变量必需显式声明。
"use strict";
v = 1; // 报错,v未声明
for(i = 0; i < 2; i++) { // 报错,i未声明
}
因而,严厉形式下,变量都必需先用var敕令声明,然后再运用。
Javascript言语的一个特性,就是许可”动态绑定”,即某些属性和要领究竟属于哪一个对象,不是在编译时肯定的,而是在运转时(runtime)肯定的。
严厉形式对动态绑定做了一些限定。某些情况下,只许可静态绑定。也就是说,属性和要领究竟归属哪一个对象,在编译阶段就肯定。如许做有利于编译效力的进步,也使得代码更轻易浏览,更少涌现意外。
因为下面的代码不是在严厉形式下实行,而且this的值不会在函数实行时被设置,此时的this的值会默许设置为全局对象。
function f2(){
"use strict"; // 这里是严厉形式
return this;
}
f2() === undefined; // true
JavaScript作用域和变量提拔
斟酌下面顺序的运转效果
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
效果是10;
再看下面这个
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
效果是1
出人意料的效果是因为“Hoisting (变量提拔)”的缘由,要明白个中的道理须要先相识下JavaScript的作用域scope。
javascript作用域(函数作用域)与C言语作用域(块级作用域)差别
int main() {
int x = 1;
printf("%d, ", x); // 1
if (1) {
int x = 2;
printf("%d, ", x); // 2
}
printf("%d\n", x); // 1
}
这是因为C家属的言语有块作用域,当顺序控制走进一个块,比方if块,只作用于该块的变量能够被声明,而不会影响块表面的作用域。然则在Javascript内里,如许不可
var x = 1;
console.log(x); // 1
if (true) {
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
函数声明和变量声明老是会被诠释器悄悄地被“提拔”到要领体的最顶部。这个意义是,像下面的代码:
function foo() {
bar();
var x = 1;
}
实际上会被诠释成:
function foo() {
var x;
bar();
x = 1;
}
不管定义该变量的块是否能被实行。下面的两个函数实际上是一回事:
function foo() {
if (false) {
var x = 1;
}
return;
var y = 1;
}
function foo() {
var x, y;
if (false) {
x = 1;
}
return;
y = 1;
}
只要函数式的声明才会连同函数体一同被提拔。foo的声明会被提拔,然则它指向的函数体只会在实行的时刻才被赋值
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // 变量指向函数表达式
alert("this won't run!");
}
function bar() { // 函数声明 函数名为bar
alert("this will run!");
}
}
test();
假如顺序员不能很好的明白变量提拔,他们写的顺序就轻易涌现一些题目。
为了防止这些题目,一般我们在每一个作用域最先前声明这些变量,这也是一般的 JavaScript 剖析步骤,易于我们明白。
JavaScript 严厉形式(strict mode)不许可运用未声明的变量。
JavaScript Object-Oriented
JavaScript组织函数
function Person (name,age) {
this.name = name;
this.age = age;
this.type = "human";
this.play = function(){console.log("video game")};
}
//下面天生实例
var Person1 = new Person("Tom",25);
var Person2 = new Person("Jack",26);
alert(Person1.name);
//这时候Person1和Person2会自动含有一个constructor属性,指向它们的组织函数。
alert(Person1.constructor);
//Javascript还供应了一个instanceof运算符,考证原型对象与实例对象之间的关联
alert(Person1 instanceof Person); //true
alert(Person1.type == Person2.type);//ture
alert(Person1.play == Person2.play);//false
type属性和play()要领都是如出一辙的内容,每一次天生一个实例,都必需为反复的内容,多占用一些内存.
Prototype形式
Javascript划定,每一个组织函数都有一个prototype属性,指向另一个对象。这个对象的一切属性和要领,都邑被组织函数的实例继续。
这意味着,我们能够把那些稳定的属性和要领,直接定义在prototype对象上.
function Person (name,age) {
this.name = name;
this.age = age;
}
Person.prototype.type = "human";
Person.prototype.play = function(){console.log("video game")};
var Person1 = new Person("Tom",25);
var Person2 = new Person("Jack",26);
alert(Person1.type); //human
alert(Person1.play == Person2.play); //true
这时候一切实例的type属性和play()要领,实在都是同一个内存地址,指向prototype对象,运用原型的优点是能够让对象实例同享它所包括的属性和要领,因而就进步了运转效力。
在JavaScript中,一共有两种范例的值,原始值和对象值。每一个对象都有一个内部属性 prototype ,我们一般称之为原型。原型的值能够是一个对象,也能够是null。假如它的值是一个对象,则这个对象也一定有本身的原型。如许就形成了一条线性的链,我们称之为原型链。
关于原型、原型链-猛戳
ECMAScript数据范例
原始范例
ECMAScript 有 5 种原始范例(primitive type),即 Undefined、Null、Boolean、Number 和 String。
原始数据范例
援用范例
援用范例一般叫做类(class),也就是说,碰到援用值,所处置惩罚的就是对象。
Object 对象
Object 对象本身用途不大,不过在相识其他类之前,照样应当相识它。因为 ECMAScript 中的 Object 对象与 Java 中的 java.lang.Object 类似,ECMAScript 中的一切对象都由这个对象继续而来,Object 对象中的一切属性和要领都邑涌现在其他对象中,所以明白了 Object 对象,就能够更好地明白其他对象。
Object 对象具有以下属性
constructor
对建立对象的函数的援用(指针)。关于 Object 对象,该指针指向原始的 Object() 函数。
Prototype
对该对象的对象原型的援用。关于一切的对象,它默许返回 Object 对象的一个实例。
范例转换
一切顺序设计言语最主要的特性之一是具有举行范例转换的才能。
ECMAScript 给开发者供应了大批简朴的范例转换要领。
- toString()
- parseInt()
- parseFloat()