Home  >  Article  >  Web Front-end  >  In-depth understanding of "Javascript Advanced Programming"

In-depth understanding of "Javascript Advanced Programming"

零下一度
零下一度Original
2017-07-18 16:04:391547browse

The book "Advanced Programming with Javascript" contains a lot of content and is very thick. I hope that other people who don't have time can generally learn the core content of the book by reading this series of excerpts.

 The content with green background is the original content that I think is more noteworthy.

 The content with the yellow background is the original content that I think is very important.

 My understanding will be marked in blue font.

This chapter has a lot of content and is relatively important. It will be recorded in two parts. This is the next part.

 5.5.4 Function internal properties

Inside a function, there are two special objects: arguments and this. Among them, arguments were introduced in Chapter 3. It is an array-like object that contains all parameters passed into the function. Although the main purpose of arguments is to save function parameters, this object also has an attribute named callee, which is a pointer to the function that owns the arguments object. Please look at the following very classic factorial function

function factorial(num){if (num <=1) {return 1;

} else {return num * factorial(num-1)

}

}

Defining the factorial function generally requires a recursive algorithm; as shown in the above code, the function has a name , and the name will not change in the future, there is no problem with this definition. But the problem is that the execution of this function is tightly coupled with the function name factorial. To eliminate this tight coupling, arguments.callee can be used as follows.

function factorial(num){if (num <=1) {return 1;

} else {return num * arguments.callee(num-1)

}

}
View Code
In this rewritten factorial() function Within the function body, the function name factorial is no longer referenced. In this way, no matter what name is used when referring to the

function, the recursive call can be guaranteed to be completed normally. For example:

var trueFactorial = factorial;

factorial = function(){return 0;

};

alert(trueFactorial(5)); //120alert(factorial(5)); //0
View Code

在此,变量 trueFactorial 获得了 factorial 的值,实际上是在另一个位置上保存了一个函数的指针。然后,我们又将一个简单地返回 0 的函数赋值给 factorial 变量。如果像原来的 factorial()那样不使用 arguments.callee,调用 trueFactorial()就会返回 0。可是,在解除了函数体内的代码与函数名的耦合状态之后, trueFactorial()仍然能够正常地计算阶乘;至于 factorial(),它现在只是一个返回 0 的函数。

函数内部的另一个特殊对象是 this,其行为与 Java 和 C#中的 this 大致类似。换句话说, this引用的是函数据以执行的环境对象——或者也可以说是 this 值(当在网页的全局作用域中调用函数时,this 对象引用的就是 window)。来看下面的例子。

window.color = "red";var o = { color: "blue" };function sayColor(){

alert(this.color);

}

sayColor(); //"red"o.sayColor = sayColor;

o.sayColor(); //"blue"
View Code

  上面这个函数 sayColor()是在全局作用域中定义的,它引用了 this 对象。由于在调用函数之前,this 的值并不确定,因此 this 可能会在代码执行过程中引用不同的对象。当在全局作用域中调用sayColor()时, this 引用的是全局对象 window;换句话说,对 this.color 求值会转换成对window.color 求值,于是结果就返回了"red"。而当把这个函数赋给对象 o 并调用 o.sayColor()时,this 引用的是对象 o,因此对 this.color 求值会转换成对 o.color 求值,结果就返回了"blue"。

  请读者一定要牢记,函数的名字仅仅是一个包含指针的变量而已。因此,即使是在不同的环境中执行,全局的 sayColor()函数与 o.sayColor()指向的仍然是同一个函数。

  ECMAScript 5 也规范化了另一个函数对象的属性:caller。除了 Opera 的早期版本不支持,其他浏览器都支持这个 ECMAScript 3 并没有定义的属性。这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为 null。例如:

function outer(){

inner();

}function inner(){

alert(inner.caller);

}

outer();
View Code

以上代码会导致警告框中显示 outer()函数的源代码。因为 outer()调用了 inter(),所以inner.caller 就指向 outer()。为了实现更松散的耦合,也可以通过 arguments.callee.caller来访问相同的信息。

function outer(){

inner();

}function inner(){

alert(arguments.callee.caller);

}

outer();
View Code

IE、 Firefox、 Chrome 和 Safari 的所有版本以及 Opera 9.6 都支持 caller 属性。

当函数在严格模式下运行时,访问 arguments.callee 会导致错误。 ECMAScript 5 还定义了arguments.caller 属性,但在严格模式下访问它也会导致错误,而在非严格模式下这个属性始终是undefined。定义这个属性是为了分清 arguments.caller 和函数的 caller 属性。以上变化都是为了加强这门语言的安全性,这样第三方代码就不能在相同的环境里窥视其他代码了。严格模式还有一个限制:不能为函数的 caller 属性赋值,否则会导致错误。

 

  5.5.5 函数属性和方法

  前面曾经提到过, ECMAScript 中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性: length 和 prototype。其中, length 属性表示函数希望接收的命名参数的个数,如下面的例子所示。

function sayName(name){

alert(name);

}function sum(num1, num2){return num1 + num2;

}function sayHi(){

alert("hi");

}

alert(sayName.length); //1alert(sum.length); //2alert(sayHi.length); //0
View Code

  在 ECMAScript 核心所定义的全部属性中,最耐人寻味的就要数 prototype 属性了。对于ECMAScript 中的引用类型而言, prototype 是保存它们所有实例方法的真正所在。换句话说,诸如toString()和 valueOf()等方法实际上都保存在 prototype 名下,只不过是通过各自对象的实例访问罢了。在创建自定义引用类型以及实现继承时, prototype 属性的作用是极为重要的(第 6 章将详细介绍)。在 ECMAScript 5 中, prototype 属性是不可枚举的,因此使用 for-in 无法发现。

  每个函数都包含两个非继承而来的方法: apply()和 call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内 this 对象的值。首先, apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。其中,第二个参数可以是 Array 的实例也可以是arguments 对象。例如:

function sum(num1, num2){return num1 + num2;

}function callSum1(num1, num2){return sum.apply(this, arguments); // 传入 arguments 对象}function callSum2(num1, num2){return sum.apply(this, [num1, num2]); // 传入数组}

alert(callSum1(10,10)); //20alert(callSum2(10,10)); //20
View Code

  在上面这个例子中, callSum1()在执行 sum()函数时传入了 this 作为 this 值(因为是在全局作用域中调用的,所以传入的就是 window 对象)和 arguments 对象。而 callSum2 同样也调用了sum()函数,但它传入的则是 this 和一个参数数组。这两个函数都会正常执行并返回正确的结果。

  call()方法与 apply()方法的作用相同,它们的区别仅在于接收参数的方式不同。对于 call()方法而言,第一个参数是 this 值没有变化,变化的是其余参数都直接传递给函数。换句话说,在使用call()方法时,传递给函数的参数必须逐个列举出来,如下面的例子所示。

function sum(num1, num2){return num1 + num2;

}function callSum(num1, num2){return sum.call(this, num1, num2);

}

alert(callSum(10,10)); //20
View Code

  在使用 call()方法的情况下, callSum()必须明确地传入每一个参数。结果与使用 apply()没有什么不同。至于是使用 apply()还是 call(),完全取决于你采取哪种给函数传递参数的方式最方便。如果你打算直接传入 arguments 对象,或者包含函数中先接收到的也是一个数组,那么使用 apply()肯定更方便;否则,选择 call()可能更合适。(在不给函数传递参数的情况下,使用哪个方法都无所谓。)

事实上,传递参数并非 apply()和 call()真正的用武之地;它们真正强大的地方是能够扩充函数赖以运行的作用域。下面来看一个例子。

window.color = "red";var o = { color: "blue" };function sayColor(){

alert(this.color);

}

sayColor(); //redsayColor.call(this); //redsayColor.call(window); //redsayColor.call(o); //blue
View Code

  这个例子是在前面说明 this 对象的示例基础上修改而成的。这一次, sayColor()也是作为全局函数定义的,而且当在全局作用域中调用它时,它确实会显示"red"——因为对 this.color 的求值会转换成对 window.color 的求值。而 sayColor.call(this)和 sayColor.call(window),则是两种显式地在全局作用域中调用函数的方式,结果当然都会显示"red"。但是,当运行 sayColor.call(o)时,函数的执行环境就不一样了,因为此时函数体内的 this 对象指向了 o,于是结果显示的是"blue"。

  使用 call()(或 apply())来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。在前面例子的第一个版本中,我们是先将 sayColor()函数放到了对象 o 中,然后再通过 o 来调用它的;而在这里重写的例子中,就不需要先前那个多余的步骤了。

ECMAScript 5 还定义了一个方法: bind()。这个方法会创建一个函数的实例,其 this 值会被绑定到传给 bind()函数的值。例如:

window.color = "red";var o = { color: "blue" };function sayColor(){

alert(this.color);

}var objectSayColor = sayColor.bind(o);

objectSayColor(); //blue

Here, sayColor() calls bind() and passes in the object o, creating the objectSayColor() function. object

The this value of the SayColor() function is equal to o, so even if this function is called in the global scope, you will see "blue". See Chapter 22 for the advantages of this technique.

Browsers that support the bind() method are IE9+, Firefox 4+, Safari 5.1+, Opera 12+ and Chrome.

The toLocaleString() and toString() methods inherited by each function always return the function code. The format of the return code varies between browsers - some return the same code as the function code in the source code, while others return an internal representation of the function code, that is, the parser removes comments and modifies certain codes. The modified code. Because of these differences, we can't do anything significant based on the results returned by these two methods; however, this information can be useful when debugging your code. Another inherited valueOf() method also only returns the function code.

5.6 Basic packaging types

In order to facilitate the operation of basic type values, ECMAScript also provides 3 special reference types: Boolean, Number and String. These types are similar to the other reference types introduced in this chapter, but also have special behavior corresponding to their respective base types. In fact, whenever a basic type value is read, a corresponding basic wrapper type object will be created in the background, allowing us to call some methods to operate on this data. Consider the following example.

var s1 = "some text";

var s2 = s1.substring(2);

The variable s1 in this example contains a string, which is of course a basic type value. The next line calls the substring() method of s1 and saves the returned result in s2. We know that primitive type values ​​are not objects, so logically they should not have methods (although, as we wish, they do). In fact, in order for us to achieve this intuitive operation, a series of processes have been automatically completed in the background. When the second line of code accesses s1, the access process is in a read mode, that is, the value of this string is read from memory. When accessing a string in read mode, the following processing will be automatically completed in the background.

(1) Create an instance of String type;

(2) Call the specified method on the instance;

(3) Destroy this instance.

The above three steps can be imagined as executing the following ECMAScript code.

var s1 = new String("some text");

##var s2 = s1.substring(2);

s1 = null;

After this processing, the basic string value becomes the same as the object. Moreover, the above three steps also apply to Boolean and numeric values ​​corresponding to the Boolean and Number types respectively. The main difference between reference types and basic wrapper types is the lifetime of the object. Instances of reference types created using the new operator remain in memory until the execution flow leaves the current scope. The automatically created basic packaging type object only exists at the moment when a line of code is executed, and then is destroyed immediately. This means that we cannot add properties and methods to primitive type values ​​at runtime.

Look at the following example:

var s1 = "some text";

s1.color = "red";

alert(s1.color); //undefined

在此,第二行代码试图为字符串 s1 添加一个 color 属性。但是,当第三行代码再次访问 s1 时,其 color 属性不见了。问题的原因就是第二行创建的 String 对象在执行第三行代码时已经被销毁了。第三行代码又创建自己的 String 对象,而该对象没有 color 属性。当然,可以显式地调用 Boolean、 Number 和 String 来创建基本包装类型的对象。不过,应该在绝对必要的情况下再这样做,因为这种做法很容易让人分不清自己是在处理基本类型还是引用类型的值。对基本包装类型的实例调用 typeof 会返回"object",而且所有基本包装类型的对象都会被转换为布尔值 true。

Object 构造函数也会像工厂方法一样,根据传入值的类型返回相应基本包装类型的实例。例如:

var obj = new Object("some text");

alert(obj instanceof String); //true

把字符串传给 Object 构造函数,就会创建 String 的实例;而传入数值参数会得到 Number 的实例,传入布尔值参数就会得到 Boolean 的实例。

要注意的是,使用 new 调用基本包装类型的构造函数,与直接调用同名的转型函数是不一样的。例如:

var value = "25";var number = Number(value); //转型函数alert(typeof number); //"number"var obj = new Number(value); //构造函数alert(typeof obj); //"object"
View Code

在这个例子中,变量 number 中保存的是基本类型的值 25,而变量 obj 中保存的是 Number 的实例。要了解有关转型函数的更多信息,请参考第 3 章。

尽管我们不建议显式地创建基本包装类型的对象,但它们操作基本类型值的能力还是相当重要的。而每个基本包装类型都提供了操作相应值的便捷方法。

5.6.1 Boolean类型

Boolean 类型是与布尔值对应的引用类型。要创建 Boolean 对象,可以像下面这样调用 Boolean构造函数并传入 true 或 false 值。

var booleanObject = new Boolean(true);

Boolean 类型的实例重写了 valueOf()方法,返回基本类型值 true 或 false;重写了 toString()

方法,返回字符串"true"和"false"。可是, Boolean 对象在 ECMAScript 中的用处不大,因为它经常会造成人们的误解。其中最常见的问题就是在布尔表达式中使用 Boolean 对象,例如:

var falseObject = new Boolean(false);var result = falseObject && true;

alert(result); //truevar falseValue = false;

result = falseValue && true;

alert(result); //false
View Code

前面讨论过,布尔表达式中的所有对象都会被转换为 true,因此 falseObject 对象在布尔表达式中代表的是 true。结果, true && true 当然就等于 true 了。

基本类型与引用类型的布尔值还有两个区别。首先, typeof 操作符对基本类型返回"boolean",而对引用类型返回"object"。其次,由于 Boolean 对象是 Boolean 类型的实例,所以使用 instanceof操作符测试 Boolean 对象会返回 true,而测试基本类型的布尔值则返回 false。例如:

alert(typeof falseObject); //objectalert(typeof falseValue); //booleanalert(falseObject instanceof Boolean); //truealert(falseValue instanceof Boolean); //false
View Code

理解基本类型的布尔值与 Boolean 对象之间的区别非常重要——当然,我们的建议是永远不要使用 Boolean 对象。

5.6.2 Number类型

Number 是与数字值对应的引用类型。要创建 Number 对象,可以在调用 Number 构造函数时向其中传递相应的数值。下面是一个例子。

var numberObject = new Number(10);

与 Boolean 类型一样, Number 类型也重写了 valueOf()、 toLocaleString()和 toString()

方法。重写后的 valueOf()方法返回对象表示的基本类型的数值,另外两个方法则返回字符串形式的数值。我们在第 3 章还介绍过,可以为 toString()方法传递一个表示基数的参数,告诉它返回几进制数值的字符串形式,如下面的例子所示。

var num = 10;

alert(num.toString()); //"10"alert(num.toString(2)); //"1010"alert(num.toString(8)); //"12"alert(num.toString(10)); //"10"alert(num.toString(16)); //"a"NumberTypeExample01.htm
View Code

除了继承的方法之外, Number 类型还提供了一些用于将数值格式化为字符串的方法。

其中, toFixed()方法会按照指定的小数位返回数值的字符串表示,例如:

var num = 10;

alert(num.toFixed(2)); //"10.00"

NumberTypeExample01.htm

这里给 toFixed()方法传入了数值 2,意思是显示几位小数。于是,这个方法返回了"10.00",即以 0 填补了必要的小数位。如果数值本身包含的小数位比指定的还多,那么接近指定的最大小数位的值就会舍入,如下面的例子所示。

var num = 10.005;

alert(num.toFixed(2)); //"10.01"

能够自动舍入的特性,使得 toFixed()方法很适合处理货币值。但需要注意的是,不同浏览器给这个方法设定的舍入规则可能会有所不同。在给 toFixed()传入 0 的情况下, IE8 及之前版本不能正确舍入范围在{(-0.94,-0.5],[0.5,0.94)}之间的值。对于这个范围内的值, IE 会返回0,而不是1或1;其他浏览器都能返回正确的值。 IE9 修复了这个问题。

5.6.3 String类型

String 类型是字符串的对象包装类型,可以像下面这样使用 String 构造函数来创建。

var stringObject = new String("hello world");

String 对象的方法也可以在所有基本的字符串值中访问到。其中,继承的 valueOf()、toLocale

String()和 toString()方法,都返回对象所表示的基本字符串值。

String 类型的每个实例都有一个 length 属性,表示字符串中包含多个字符。来看下面的例子。

var stringValue = "hello world";

alert(stringValue.length); //"11"

这个例子输出了字符串"hello world"中的字符数量,即"11"。应该注意的是,即使字符串中包含双字节字符(不是占一个字节的 ASCII 字符),每个字符也仍然算一个字符。

String 类型提供了很多方法,用于辅助完成对 ECMAScript 中字符串的解析和操作。

1. 字符方法

两个用于访问字符串中特定字符的方法是: charAt()和 charCodeAt()

2. 字符串操作方法

下面介绍与操作字符串有关的几个方法。第一个就是 concat(),用于将一或多个字符串拼接起来,返回拼接得到的新字符串。先来看一个例子。

var stringValue = "hello ";var result = stringValue.concat("world");

alert(result); //"hello world"alert(stringValue); //"hello"
View Code

ECMAScript还提供了三个基于子字符串创建新字符串的方法:slice()、substr()和substring()。这三个方法都会返回被操作字符串的一个子字符串,而且也都接受一或两个参数。第一个参数指定子字符串的开始位置,第二个参数(在指定的情况下)表示子字符串到哪里结束。具体来说, slice()和substring()的第二个参数指定的是子字符串最后一个字符后面的位置。而 substr()的第二个参数指定的则是返回的字符个数。如果没有给这些方法传递第二个参数,则将字符串的长度作为结束位置。与concat()方法一样, slice()、 substr()和 substring()也不会修改字符串本身的值——它们只是返回一个基本类型的字符串值,对原始字符串没有任何影响。请看下面的例子。

var stringValue = "hello world";

alert(stringValue.slice(3)); //"lo world"alert(stringValue.substring(3)); //"lo world"alert(stringValue.substr(3)); //"lo world"alert(stringValue.slice(3, 7)); //"lo w"alert(stringValue.substring(3,7)); //"lo w"alert(stringValue.substr(3, 7)); //"lo worl"
View Code

3. 字符串位置方法

有两个可以从字符串中查找子字符串的方法: indexOf()和 lastIndexOf()。这两个方法都是从

一个字符串中搜索给定的子字符串,然后返子字符串的位置(如果没有找到该子字符串,则返回-1)。这两个方法的区别在于: indexOf()方法从字符串的开头向后搜索子字符串,而 lastIndexOf()方法是从字符串的末尾向前搜索子字符串。还是来看一个例子吧。

var stringValue = "hello world";

alert(stringValue.indexOf("o")); //4

alert(stringValue.lastIndexOf("o")); //7

4. trim()方法

ECMAScript 5 为所有字符串定义了 trim()方法。这个方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果。例如:

var stringValue = " hello world ";var trimmedStringValue = stringValue.trim();

alert(stringValue); //" hello world "alert(trimmedStringValue); //"hello world"
View Code

5. 字符串大小写转换方法

接下来我们要介绍的是一组与大小写转换有关的方法。 ECMAScript 中涉及字符串大小写转换的方法有 4 个: toLowerCase()、 toLocaleLowerCase()、 toUpperCase()和 toLocaleUpperCase()

7. localeCompare()方法

与操作字符串有关的最后一个方法是 localeCompare(),这个方法比较两个字符串,并返回下列值中的一个:

q 如果字符串在字母表中应该排在字符串参数之前,则返回一个负数(大多数情况下是-1,具体的值要视实现而定);

q 如果字符串等于字符串参数,则返回 0;

q 如果字符串在字母表中应该排在字符串参数之后,则返回一个正数(大多数情况下是 1,具体的值同样要视实现而定)。

下面是几个例子。

var stringValue = "yellow";

alert(stringValue.localeCompare("brick")); //1alert(stringValue.localeCompare("yellow")); //0alert(stringValue.localeCompare("zoo")); //-1
View Code

5.7 Single built-in object

ECMA-262 defines built-in objects as: “Objects provided by the ECMAScript implementation that do not depend on the host environment. These objects Exists before the ECMAScript program is executed. This means that developers do not have to explicitly instantiate built-in objects because they are already instantiated. We have already introduced most of the built-in objects such as Object, Array and String.

ECMA-262 also defines two singleton built-in objects: Global and Math.

5.7.1 Global Object

## The Global object can be said to be the most special object in ECMAScript , because no matter which angle you look at it, this object does not exist. The Global object in ECMAScript is defined in a sense as the ultimate "catch-all object". In other words, properties and methods that do not belong to any other object are ultimately its properties and methods. In fact, there are no global variables or functions; all properties and functions defined in the global scope are properties of the Global object. The functions introduced earlier in this book, such as isNaN(), isFinite(), parseInt(), and parseFloat(), are actually all methods of the Global object. In addition to this, the Global object also contains some other methods.

1. URI encoding method

The encodeURI() and encodeURIComponent() methods of the Global object can encode URI (Uniform Resource

Identifiers, Universal Resource Identifiers) are encoded to be sent to the browser. Certain characters, such as spaces, cannot be included in a valid URI. These two URI encoding methods can encode the URI. They replace all invalid characters with special UTF-8 encoding so that the browser can accept and understand it.

2. eval() method

Now, we introduce the last one - probably the most powerful method in the entire ECMAScript language :eval(). The eval() method is like a complete ECMAScript parser, it only accepts one parameter, the ECMAScript (or JavaScript) string to be executed. Look at the following example:

eval("alert('hi')");

The effect of this line of code is equivalent to the following This line of code:

alert("hi");

When the parser finds that the eval() method is called in the code, it will Parses the passed parameters as actual ECMAScript statements and inserts the execution results into the original position. Code executed via eval() is considered part of the execution environment containing the call, so the code being executed has the same scope chain as that execution environment. This means that code executed via eval() can reference variables defined in the containing environment, for example:

var msg = "hello world";

eval("alert(msg)"); //"hello world"

It can be seen that the variable msg is defined outside the environment where eval() is called , but the alert() called there can still display "hello world". This is because the second line of code above is eventually replaced with a real line of code. Similarly, we can also define a function in the eval() call and then reference the function in the external code of the call:

eval("function sayHi() { alert ('hi'); }");

##sayHi();

Obviously, the function sayHi() is inside eval() Defined. But since the call to eval() will eventually be replaced by the actual code defining function

, sayHi() can be called on the next line. The same goes for variables:

eval("var msg = 'hello world'; ");

alert(msg); //"hello world"

在 eval()中创建的任何变量或函数都不会被提升,因为在解析代码的时候,它们被包含在一个字符串中;它们只在 eval()执行的时候创建。

严格模式下,在外部访问不到 eval()中创建的任何变量或函数,因此前面两个例子都会导致错误。同样,在严格模式下,为 eval 赋值也会导致错误:

"use strict";

eval = "hi"; //causes error

能够解释代码字符串的能力非常强大,但也非常危险。因此在使用 eval()时必须极为谨慎,特别是在用它执行用户输入数据的情况下。否则,可能会有恶意用户输入威胁你的站点或应用程序安全的代码(即所谓的代码注入)。

3. Global 对象的属性

Global 对象还包含一些属性,其中一部分属性已经在本书前面介绍过了。例如,特殊的值

undefined、 NaN 以及 Infinity 都是 Global 对象的属性。此外,所有原生引用类型的构造函数,像Object 和 Function,也都是 Global 对象的属性。下表列出了 Global 对象的所有属性。

undefined 特殊值undefined Date 构造函数Date

NaN 特殊值NaN RegExp 构造函数RegExp

Infinity 特殊值Infinity Error 构造函数Error

Object 构造函数Object EvalError 构造函数EvalError

Array 构造函数Array RangeError 构造函数RangeError

Function 构造函数Function ReferenceError 构造函数ReferenceError

Boolean 构造函数Boolean SyntaxError 构造函数SyntaxError

String 构造函数String TypeError 构造函数TypeError

Number 构造函数Number URIError 构造函数URIError

ECMAScript 5 明确禁止给 undefined、 NaN 和 Infinity 赋值,这样做即使在非严格模式下也会导致错误。

4. window 对象

ECMAScript 虽然没有指出如何直接访问 Global 对象,但 Web 浏览器都是将这个全局对象作为window 对象的一部分加以实现的。因此,在全局作用域中声明的所有变量和函数,就都成为了 window对象的属性。来看下面的例子。

var color = "red";function sayColor(){

alert(window.color);

}

window.sayColor(); //"red"
View Code

In addition to playing the role of the Global object specified by ECMAScript, the window object in JavaScript

also undertakes many other tasks. The window object is discussed in detail in Chapter 8 when we discuss the browser object model.

5.7.2 Math object

ECMAScript also provides a common location for saving mathematical formulas and information, the Math object. The calculation functions provided by the Math object perform much faster than the calculation functions we write directly in JavaScript. The Math object also provides properties and methods to assist in completing these calculations.

1. Properties of the Math object

The properties contained in the Math object are mostly special values ​​that may be used in mathematical calculations. The following table lists these properties.

While discussing the meaning and use of these values ​​is beyond the scope of this book, you can indeed use them at any time.

2. min() and max() methods

The Math object also contains many methods to assist in completing simple and complex mathematics. calculate.

The min() and max() methods are used to determine the minimum and maximum values ​​in a set of values. Both methods can accept any number of numeric arguments, as shown in the following example.

var max = Math.max(3, 54, 32, 16);

##alert(max); //54

var min = Math.min(3, 54, 32, 16);

alert(min); //3

3. Rounding methods

The following are several methods for rounding decimal values ​​into integers: Math.ceil(), Math.floor( ) and Math.round().

These three methods follow the following rounding rules respectively:

Math.ceil() performs upward rounding, that is, it always rounds The value is rounded up to the nearest integer;

Math.floor() performs rounding down, that is, it always rounds the value down to the nearest integer;

Math.round() performs standard rounding, i.e. it always rounds the value to the nearest integer (this is also the rounding rule we learned in math class).

4. random() method

The Math.random() method returns a random number greater than or equal to 0 and less than 1. For some sites, this method is very practical, because it can be used to randomly display some famous quotes and news events. Applying the following formula, you can use Math.random() to randomly select a value from a certain range of integers.

Value = Math.floor(Math.random() * total number of possible values ​​+ first possible value)

5. Other methods

5.8 Summary

Objects are called in JavaScript Reference type values, and there are some built-in reference types that can be used to create specific objects. A brief summary is as follows:

Reference types are similar to classes in traditional object-oriented programming. But the implementation is different;

Object is a basic type, and all other types inherit basic behaviors from Object;

The Array type is an ordered list of a set of values, and also provides Provides functions for manipulating and converting these values;

The Date type provides information about dates and times, including the current date and time and related calculation functions;

The RegExp type is an interface for ECMAScript to support regular expressions, providing the most basic and some advanced regular expression functions.

Functions are actually instances of the Function type, so functions are also objects; and this is the most distinctive feature of JavaScript. Since functions are objects, they also have methods that can be used to enhance their behavior.

Because of the basic wrapper type, basic type values ​​in JavaScript can be accessed as objects. The three basic wrapper types are: Boolean, Number, and String. The following are their common characteristics:

Each wrapper type maps to a basic type with the same name;

The basic type is accessed in read mode type value, an object of the corresponding basic packaging type will be created, thus facilitating data operations;

Once the statement that operates the basic type value is executed, the newly created object will be destroyed immediately The packaging object.

Before all code is executed, two built-in objects already exist in the scope: Global and Math. The Global object is not directly accessible in most ECMAScript implementations; however, web browsers implement a window object that assumes this role. Global variables and functions are properties of the Global object. The Math object provides many properties and methods to assist in completing complex mathematical calculation tasks.

The above is the detailed content of In-depth understanding of "Javascript Advanced Programming". For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn