Maison > Article > interface Web > Compréhension approfondie de la « programmation avancée Javascript »
Javascript Advanced Programming Ce livre contient beaucoup de contenu et est très épais. J'espère que d'autres personnes qui n'ont pas le temps pourront lire cette série d'extraits et généralement apprendre le contenu principal du livre.
Le contenu sur fond vert est le contenu original qui, à mon avis, est le plus remarquable.
Le contenu avec le fond jaune est le contenu original que je trouve très important.
Ma compréhension sera marquée en caractères bleus.
Ce chapitre a beaucoup de contenu et est relativement important. Il sera enregistré en deux parties. C'est la partie suivante.
À l'intérieur d'une fonction, il y a deux objets spéciaux : les arguments et ceci. Parmi eux, les arguments ont été introduits au chapitre 3. Il s'agit d'un objet de type tableau qui contient tous les paramètres passés dans la fonction. Bien que l'objectif principal des arguments soit de sauvegarder les paramètres de la fonction, cet objet possède également un attribut appelé appelé, qui est un pointeur vers la fonction propriétaire de l'objet arguments. Veuillez regarder la fonction factorielle très classique suivante
function factorial(num){if (num <=1) {return 1; } else {return num * factorial(num-1) } }Définir la fonction factorielle nécessite généralement un algorithme récursif comme indiqué dans le code ci-dessus, dans la fonction ; S'il existe un nom et que celui-ci ne changera pas à l'avenir, cette définition ne pose aucun problème. Mais le problème est que l’exécution de cette fonction est étroitement liée au nom de fonction factorielle. Pour éliminer ce couplage étroit, arguments.callee peut être utilisé comme suit.
function factorial(num){if (num <=1) {return 1; } else {return num * arguments.callee(num-1) } }
, l'appel récursif peut être assuré de se terminer normalement. Par exemple :
var trueFactorial = factorial; factorial = function(){return 0; }; alert(trueFactorial(5)); //120alert(factorial(5)); //0
在此,变量 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"
上面这个函数 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();
以上代码会导致警告框中显示 outer()函数的源代码。因为 outer()调用了 inter(),所以inner.caller 就指向 outer()。为了实现更松散的耦合,也可以通过 arguments.callee.caller来访问相同的信息。
function outer(){ inner(); }function inner(){ alert(arguments.callee.caller); } outer();
IE、 Firefox、 Chrome 和 Safari 的所有版本以及 Opera 9.6 都支持 caller 属性。
当函数在严格模式下运行时,访问 arguments.callee 会导致错误。 ECMAScript 5 还定义了arguments.caller 属性,但在严格模式下访问它也会导致错误,而在非严格模式下这个属性始终是undefined。定义这个属性是为了分清 arguments.caller 和函数的 caller 属性。以上变化都是为了加强这门语言的安全性,这样第三方代码就不能在相同的环境里窥视其他代码了。严格模式还有一个限制:不能为函数的 caller 属性赋值,否则会导致错误。
前面曾经提到过, 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
在 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
在上面这个例子中, 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
在使用 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
这个例子是在前面说明 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
Ici, sayColor() appelle bind() et transmet l'objet o, créant la fonction objectSayColor(). La valeur this de la fonction object
SayColor() est égale à o, donc même si cette fonction est appelée dans la portée globale, vous verrez "bleu". Voir le chapitre 22 pour les avantages de cette technique.
Les navigateurs qui prennent en charge la méthode bind() sont IE9+, Firefox 4+, Safari 5.1+, Opera 12+ et Chrome.
Les méthodes toLocaleString() et toString() héritées par chaque fonction renvoient toujours le code de la fonction. Le format du code de retour varie selon les navigateurs : certains renvoient le même code que le code de fonction dans le code source, tandis que d'autres renvoient une représentation interne du code de fonction, c'est-à-dire que l'analyseur supprime les commentaires et modifie certains codes. . En raison de ces différences, nous ne pouvons rien faire de significatif sur la base des résultats renvoyés par ces deux méthodes. Cependant, ces informations peuvent être utiles lors du débogage du code ; Une autre méthode héritée valueOf() renvoie également uniquement le code de la fonction.
Afin de faciliter la manipulation des valeurs de type de base, ECMAScript fournit également 3 types de référence spéciaux : Booléen, Nombre et Chaîne. Ces types sont similaires aux autres types de référence présentés dans ce chapitre, mais ont également un comportement spécial correspondant à leurs types de base respectifs. En fait, chaque fois qu'une valeur de type de base est lue, un objet de type wrapper de base correspondant sera créé en arrière-plan, nous permettant d'appeler certaines méthodes pour opérer sur ces données. Considérez l'exemple suivant.
var s1 = "du texte";
var s2 = s1.substring(2);
La variable s1 dans cet exemple contient une chaîne, qui est bien sûr une valeur de type de base. La ligne suivante appelle la méthode substring() de s1 et enregistre le résultat renvoyé dans s2. Nous savons que les valeurs primitives ne sont pas des objets, donc logiquement elles ne devraient pas avoir de méthodes (même si, comme nous le souhaitons, elles en ont). En fait, pour réaliser cette opération intuitive, une série de processus ont été automatiquement complétés en arrière-plan. Lorsque la deuxième ligne de code accède à s1, le processus d'accès est en mode lecture, c'est-à-dire que la valeur de cette chaîne est lue dans la mémoire. Lors de l'accès à une chaîne en mode lecture, le traitement suivant sera automatiquement effectué en arrière-plan.
(1) Créer une instance de type String
(2) Appeler la méthode spécifiée sur l'instance
(3) Détruisez cette instance.
Les trois étapes ci-dessus peuvent être imaginées comme l'exécution du code ECMAScript suivant.
var s1 = new String("du texte");
var s2 = s1.substring(2);
s1 = null;
Après ce traitement, la valeur de la chaîne de base devient la même que celle de l'objet. De plus, les trois étapes ci-dessus s'appliquent également aux valeurs booléennes et numériques correspondant respectivement aux types Booléen et Numérique. La principale différence entre les types référence et les types wrapper de base est la durée de vie de l'objet. Les instances de types référence créées à l'aide de l'opérateur new restent en mémoire jusqu'à ce que le flux d'exécution quitte la portée actuelle. L'objet de type packaging de base créé automatiquement n'existe qu'au moment où une ligne de code est exécutée, puis est immédiatement détruit. Cela signifie que nous ne pouvons pas ajouter de propriétés et de méthodes aux valeurs de type primitif au moment de l'exécution.
Regardez l'exemple suivant :
var s1 = "some text";
s1.color = "rouge";
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"
在这个例子中,变量 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
前面讨论过,布尔表达式中的所有对象都会被转换为 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
理解基本类型的布尔值与 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
除了继承的方法之外, 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"
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"
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"
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
ECMA-262 définit les objets intégrés comme : "Objets fournis par l'implémentation ECMAScript qui ne dépendent pas de l'environnement hôte. Ces objets existent avant l'exécution du programme ECMAScript. Cela signifie que les développeurs n'ont pas besoin d'instancier explicitement les objets intégrés car ils sont déjà instanciés. Nous avons déjà présenté la plupart des objets intégrés tels que Object, Array et String.
ECMA-262 définit également deux objets intégrés uniques : Global et Math.
5.7.1 Objet global
L'objet Global peut être considéré comme l'objet le plus spécial d'ECMAScript , car quel que soit l’angle sous lequel on le regarde, cet objet n’existe pas. L'objet Global dans ECMAScript est défini en un sens comme l'ultime « objet fourre-tout ». En d’autres termes, les propriétés et méthodes qui n’appartiennent à aucun autre objet sont en fin de compte ses propriétés et méthodes. En fait, il n'y a pas de variables ou de fonctions globales ; toutes les propriétés et fonctions définies dans la portée globale sont des propriétés de l'objet Global. Les fonctions présentées plus tôt dans ce livre, telles que isNaN(), isFinite(), parseInt() et parseFloat(), sont en réalité toutes des méthodes de l'objet Global. En plus de cela, l'objet Global contient également d'autres méthodes.
1. Méthode d'encodage URI
Les méthodes encodeURI() et encodeURIComponent() de l'objet Global peuvent encoder des URI (Uniform Resource
Identifiants, Universal Resource Identifiers) sont codés pour être envoyés au navigateur. Certains caractères, tels que les espaces, ne peuvent pas être inclus dans un URI valide. Ces deux méthodes de codage URI peuvent coder l'URI. Elles remplacent tous les caractères invalides par un codage UTF-8 spécial afin que le navigateur puisse l'accepter et le comprendre.
2. Méthode eval()
Maintenant, nous présentons la dernière - probablement la méthode la plus puissante de tout le langage ECMAScript : eval (). La méthode eval() est comme un analyseur ECMAScript complet, elle n'accepte qu'un seul paramètre, la chaîne ECMAScript (ou JavaScript) à exécuter. Regardez l'exemple suivant :
eval("alert('hi')");
L'effet de cette ligne de code est équivalent à la ligne de code suivante :
alert("hi");
Lorsque l'analyseur constate que la méthode eval() est appelé dans le code, il analysera les paramètres transmis en tant qu'instructions ECMAScript réelles et insère les résultats de l'exécution dans la position d'origine. Le code exécuté via eval() est considéré comme faisant partie de l'environnement d'exécution contenant l'appel, donc le code en cours d'exécution a la même chaîne de portée que cet environnement d'exécution. Cela signifie que le code exécuté via eval() peut référencer des variables définies dans l'environnement conteneur, par exemple :
var msg = "hello world";
eval("alert(msg)"); //"hello world"
On voit que la variable msg est définie en dehors de l'environnement où eval() est appelé , mais l'alerte() appelée ici peut toujours afficher "hello world". En effet, la deuxième ligne de code ci-dessus est finalement remplacée par une vraie ligne de code. De même, on peut également définir une fonction dans l'appel eval() puis référencer la fonction dans le code externe de l'appel :
eval("function sayHi() { alert (' hi'); }");
sayHi();
Évidemment, la fonction sayHi() est définie dans eval(). Mais puisque l'appel à eval() est finalement remplacé par le code réel qui définit la fonction
, sayHi() peut être appelé sur la ligne suivante. Il en va de même pour les 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"
En plus de jouer le rôle de l'objet Global spécifié par ECMAScript, l'objet window en JavaScript
assume également de nombreuses autres tâches. L'objet window est abordé en détail au chapitre 8 lorsque nous discutons du modèle objet du navigateur.
5.7.2 Objet Math
ECMAScript fournit également un emplacement commun pour enregistrer des formules et des informations mathématiques, l'objet Math. Les fonctions de calcul fournies par l'objet Math fonctionnent beaucoup plus rapidement que les fonctions de calcul que nous écrivons directement en JavaScript. L'objet Math fournit également des propriétés et des méthodes pour vous aider à effectuer ces calculs.
1. Propriétés de l'objet Math
La plupart des propriétés contenues dans l'objet Math sont des valeurs spéciales qui peuvent être utilisées dans calculs mathématiques. Le tableau suivant répertorie ces propriétés.
Bien que discuter du sens et de l'utilisation de ces valeurs dépasse le cadre de ce livre, vous pouvez en effet utiliser eux à tout moment.
2. Méthodes min() et max()
L'objet Math contient également de nombreuses méthodes pour aider à effectuer des calculs mathématiques simples et complexes. .
Parmi elles, les méthodes min() et max() sont utilisées pour déterminer les valeurs minimales et maximales dans un ensemble de valeurs. Les deux méthodes peuvent accepter n'importe quel nombre d'arguments numériques, comme le montre l'exemple suivant.
var max = Math.max(3, 54, 32, 16);
alerte(max); >
var min = Math.min(3, 54, 32, 16);
alerte(min);
3. Méthodes d'arrondi
Voici quelques méthodes pour arrondir les valeurs décimales en nombres entiers : Math.ceil(), Math.floor() et Math. .rond().
Ces trois méthodes suivent respectivement les règles d'arrondi suivantes :
Math.ceil() effectue un arrondi vers le haut, c'est-à-dire qu'il arrondit toujours les valeurs sont arrondis à l'entier le plus proche ;
Math.floor() effectue un arrondi à l'entier inférieur, c'est-à-dire qu'il arrondit toujours la valeur à l'entier inférieur le plus proche ;
Math.round() effectue un arrondi standard, c'est-à-dire qu'il arrondit toujours une valeur à l'entier le plus proche (c'est aussi la règle d'arrondi que nous avons apprise en cours de mathématiques).
4. Méthode random()
La méthode Math.random() renvoie un nombre aléatoire supérieur ou égal à 0 et inférieur à 1. . Pour certains sites, cette méthode est très pratique, car elle peut être utilisée pour afficher de manière aléatoire des citations et des événements d’actualité célèbres. En appliquant la formule suivante, vous pouvez utiliser Math.random() pour sélectionner aléatoirement une valeur parmi une certaine plage d'entiers.
Valeur = Math.floor(Math.random() * nombre total de valeurs possibles + première valeur possible)
5. Autres méthodes
Les objets sont appelés en type de référence JavaScript valeurs, et certains types de référence intégrés peuvent être utilisés pour créer des objets spécifiques. Un bref résumé est le suivant :
Les types de référence sont similaires aux classes orientées objet traditionnelles. la programmation. Mais la mise en œuvre est différente
Object est un type de base, et tous les autres types héritent des comportements de base d'Object
Le type Array est une liste ordonnée d'un ensemble de valeurs et fournit également Fournit des fonctions pour manipuler et convertir ces valeurs ;
Le type Date fournit des informations sur les dates et les heures, y compris la date et l'heure actuelles et les fonctions de calcul associées
Le type RegExp est une interface d'ECMAScript qui prend en charge les expressions régulières, fournissant les fonctions d'expression régulière les plus basiques et certaines avancées.
Les fonctions sont en fait des instances du type Function, donc les fonctions sont également des objets et c'est la caractéristique la plus distinctive de JavaScript ; Puisque les fonctions sont des objets, elles disposent également de méthodes qui peuvent être utilisées pour améliorer leur comportement.
En raison du type de wrapper de base, les valeurs de type de base en JavaScript sont accessibles en tant qu'objets. Les trois types de wrapper de base sont : Boolean, Number et String. Voici leurs caractéristiques communes :
Chaque type de wrapper correspond à un type de base portant le même nom
Le type de base est accessible dans valeur de type de mode de lecture, un objet du type d'emballage de base correspondant sera créé, facilitant ainsi les opérations sur les données
Une fois l'instruction qui exploite la valeur de type de base exécutée, l'objet nouvellement créé ; sera détruit immédiatement l'objet d'emballage.
Avant que tout le code ne soit exécuté, deux objets intégrés existent déjà dans la portée : Global et Math. L'objet Global n'est pas directement accessible dans la plupart des implémentations ECMAScript ; cependant, les navigateurs Web implémentent un objet window qui assume ce rôle. Les variables et fonctions globales sont des propriétés de l'objet Global. L'objet Math fournit de nombreuses propriétés et méthodes pour vous aider à effectuer des tâches de calcul mathématique complexes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!