Maison > interface Web > js tutoriel > le corps du texte

Explication des connaissances de base de javascript

高洛峰
Libérer: 2017-01-21 09:17:20
original
1203 Les gens l'ont consulté

Cet article convient aux novices en JavaScript ou aux étudiants qui ont étudié le front-end depuis un certain temps et n'ont pas de notion claire de JS~~.

Objectif de l'apprentissage

Cet article s'adresse aux étudiants ayant de faibles bases JavaScript afin d'approfondir leur compréhension de JavaScript.

Cet article décrira les pièges suivants pour les débutants lorsqu'ils commencent à parler JavaScript (dont certains sont courants dans la plupart des langues)

Le contenu de l'explication est le suivant :

1. En attente

2. i

3. Objet d'emballage

4. >Partie explicative

1. Etc.

Essayez-le

Etc est une expression courante, mais toutes les situations ne conviennent pas à Etc. Etc. littéraux et non littéraux. S'applique aux types de référence.

Les codes ci-dessus sont des affectations consécutives courantes. Parfois, nous avons besoin d'attribuer deux variables à une valeur en même temps. Cependant, s'il s'agit de types de référence, ils ne peuvent pas l'être. attribués consécutivement.

De plus, il y a une grosse faille dans l'affectation continue, à savoir que la variable sera divulguée dans le monde global. Nous ne l'avons pas divulguée dans le code ci-dessus, mais regardez le code suivant :
// 字面量连等得到想要的结果
var a,b;
a = b = 2;
a // 2
b // 2
// 引用类型连等不可预测
var arr1, arr2;
arr1 = arr2 = []
arr1[0] = 10
arr2[0] // 10
//引用类型连等使得两个引用指向一个对象,操作其中一个,两个值都变
Copier après la connexion

Comme vous pouvez le voir, après avoir exécuté la fonction fn, la variable b apparaît dans la portée globale. Pourquoi ? Regardez la phrase var a = b = num.

Nous n'avons en fait déclaré que la variable a, et le b consécutif n'a pas été déclaré. À partir de là, nous pouvons savoir que b est accroché à l'objet fenêtre global, provoquant une fuite de la variable dans le monde.
function fn (num) {
 var a = b = num;
 a // num
 b // num
}
fn(10)
a // 报错
b // 10
// 我们并不没有定义全局变量b
Copier après la connexion

Débutant

var a
a = b = num
//只声明了a
Copier après la connexion
Ce qui précède n'est qu'un exemple simple. Examinons ensuite un exemple plus complexe

Cet exemple a été vu dans une question test. premier coup d'œil À première vue, cela semble flou, mais ce n'est pas du tout difficile à comprendre.

1. a et b font référence à des types, pointant tous deux vers un objet {x : 1}

var a = {x: 1}
var b = a
a.x = a = {y: 1}
a.x // undefined
b.x // {y: 1}
Copier après la connexion
2 a.x fait référence à l'attribut x de l'objet d'origine, et a est une variable de référence.

3. a = {y : 1} pointe simplement le pointeur de la variable de référence a vers un autre objet {y : 1}

4. L'attribut x de l'objet, c'est-à-dire l'attribut x de l'objet référencé par b

5 La mission est terminée.

Peut-être que vous ne l'avez pas encore compris, ne vous inquiétez pas, ci-dessous nous allons décortiquer le moteur javascript afin que vous puissiez le comprendre clairement

庖丁解牛

Le principe de fonctionnement du moteur : le moteur analyse. Lors de l'utilisation d'expressions JavaScript, les requêtes LHS et RHS seront effectuées (voir "Javascript que vous ne connaissez pas" pour plus de détails. Je les comprends comme LHS (affectation) et RHS (recherche). .

Ensuite, démontrons le flux de travail du moteur sur la base de l'exemple ci-dessus

2. Opérateurs

Les opérateurs les plus couramment utilisés n'ont en fait rien de spécial. C'est une chose étrange. , mais le comprenez-vous vraiment si vous êtes novice ?

var a = {x: 1}
// 引擎:我将要对a变量LHS(赋值),内容是{x: 1}
// 作用域: 刚声明了a变量,给你。
var b = a
// 引擎: 我将要对a变量RHS(查找)
// 作用域: 你刚刚给它LHS了,给你吧
// 引擎: 我将要对b变量LHS(赋值),内容为a变量指向的对象
// 作用域:刚声明了b变量,给你。
a.x = a = {y: 1}
// 引擎:我将要对a进行LHS(赋值),内容是另一个对象{y:1}
// 作用域:可以,给你,但好像还有其他命令,先不要赋值。
// 引擎: 是的,下一步我还需要对a.x 进行LHS(赋值),内容是将要改变的a变量
// 作用域: 可以,a变量指向的对象有x属性,不过马上a就改变了,不过没关系,b变量也指向那个对象,赋值完后,你可以用b变量引用旧对象。
// 引擎:了解了,我先把a变量赋值为一个新的对象,然后把原来的a变量指向的对象的x属性赋值为 新a。
a.x // undefined
// 引擎: 我需要拿到a变量指向的对象的x属性
// 作用域: 你刚刚改变了a的指向,现在的a指向的对象已经没有x属性了
b.x // {y: 1}
// 引擎: 我需要拿到b变量指向的对象的x属性
// 作用域: 你是想拿到你旧对象的x属性吧,给你,不过已经被你在之前改变了值,现在b.x的值就是a指向的新对象的值。
Copier après la connexion

Avant et Après , l'un consiste à renvoyer la valeur après que l'expression soit incrémentée et l'autre consiste à renvoyer la valeur avant que l'expression ne soit incrémentée. Nous pouvons décomposer les deux et examiner le processus.

C’est juste une question d’ordre des opérations. Cela peut être facile à comprendre, mais il y a aussi un piège, comme suit.
var a = 1;
var b = a++
a // 2
b // 1
var c = 1;
var d = ++ c;
c // 2
d // 2
Copier après la connexion

Il y a quelques jours, une personne a demandé : Combien fait 1 ? Réponse : 2

b = a++
// 等价于 ...
b = a
a = a + 1
//.........................
b = ++ a
// 等价于 ...
a = a + 1
b = a
Copier après la connexion
Je suppose que la première réaction de beaucoup de gens est 2, mais c'est totalement faux ! Alors pourquoi n'est-il pas égal à 2 ? En fait, 1 est une erreur et n'est pas une expression légale. Les raisons sont les suivantes :

3. en utilisant une chaîne pour obtenir la longueur, lorsque vous utilisez l'interception de méthode et d'autres comportements, avez-vous déjà pensé : une valeur littérale n'est qu'une valeur. Pourquoi a-t-elle des attributs de méthode ? Il est vrai que les objets n'existent que, mais lorsque l'expression est exécutée, un objet de packaging est généré. Peut-être avez-vous lu ce point de connaissances et pouvez-vous l'ignorer.

Nous définissons une chaîne str et obtenons la longueur de 5, mais nous ajoutons nous-mêmes un attribut aaa et ne pouvons pas l'obtenir. Cela doit être résolu par le cycle de déclaration de l'objet d'emballage : le cycle de déclaration. de l'objet d'empaquetage n'existe que dans une expression
1 ++
// 等价于
1 = 1 + 1
// 引擎对 1 进行LHS(赋值),作用域发现他是非法变量,所以会报错 左值无效。
Copier après la connexion

En d'autres termes, chaque fois que l'attribut str est utilisé, il est d'abord empaqueté dans un objet String. Une fois l'opération terminée, l'objet est libéré. .On peut voir que les deux str.aaa ci-dessus sont des objets différents, donc bien sûr, l'attribut aaa n'est pas obtenu la deuxième fois. Si vous ne comprenez pas, vous pouvez rechercher l'objet d'emballage js sur Baidu pour obtenir des réponses détaillées.

4. Types de référence
var str = 'hello'
str.length // 5
str.aaa = 5
str.aaa // undefined
Copier après la connexion

La plupart des langages ont des types de référence, qui sont en fait des variables d'objet. En langage C, nous comprenons le type référence comme un pointeur. Ce pointeur pointe dynamiquement vers un morceau de mémoire grâce aux modifications du code, le pointage du pointeur changera en conséquence. Il en va de même pour js.

var str = 'hello'
str.length
// 等价于
new String(str).length
str.aaa = 5
//等价于
new String(str).aaa = 5
str.aaa
// 等价于
new String(str).aaa
Copier après la connexion
Lorsque nous écrivons du code, nous devons nous rappeler la différence entre les variables de type référence et les variables littérales. Elles ont des utilisations différentes.

Ceci est un exemple dans "Javascript Advanced Programming". Nous passons un objet global à la fonction setColor et effectuons les opérations ci-dessus en interne. Nous imprimons que global.color est bleu, pourquoi pas ? ? Voici le résultat du type référence.

1. La variable globale est un type référence, qui pointe vers un objet,

2. Lorsqu'elle est transmise à la fonction setColor, obj fait référence à l'objet pointé par global (ci-après dénommé). as globalObj)

var global = new Object()
function setColor (obj) {
 obj.color = 'blue'
 obj = new Object()
 obj.color = 'red'
}
setColor(global)
global.color // blue
Copier après la connexion
3. Attribuez un attribut de couleur à globalObj sous forme de chaîne bleue, puis global.color est bleu

4. Pointez obj vers un autre nouvel objet localObj, afin que obj soit déconnecté de. mondial.

5. Attribuez localObj.color à « rouge »

可以看出,我们并没有对global对象的color进行'red'赋值,'red'赋值给了另一个对象的color属性。

结论:引用类型传递是将两个变量指向同一个对象,而字面量的传递仅仅是值的赋值传递。我们可以将引用类型传递到函数进行改变,不可以在函数内改变传递进来的字面值。

5. && 与 ||

两者的基本运用相信大家都了解,大部分用来if判断,如:

var a = 2;
var b = false
if (a && b) {
 
 alert('best')
}
if (a || b) {
 alret('good')  // 运行
}
Copier après la connexion

他们的用法不局限于判断 左右两边的 && 和 || 关系,还可以用来提供代码的质量

var obj = {}
if (obj.info.user === 'xu') { // terrible
 // ..
}
if (obj.info && obj.info.user === 'xu' ) { // good
 // ...
}
Copier après la connexion

如果仅仅判断obj.info.user 会报错造成程序终止,但是下面那样判断就大使得代码健壮,不会那么容易崩溃。

重点: && 和 || 并不会返回true和false,他会返回终止此表达式的那个变量值。

true && 6 // 6
NaN && false // NaN
'0' || 6 // '0'
false || true // true
false || 0 && 1 // 0
false || 1 && 0 // 0
Copier après la connexion

&&和||, &&优先级大于||。

&&操作符,如果左边为假,返回左边值,否则,始终返回右边值

||操作符,如果左边为真,返回左边值, 否则,始终返回右边值。

结尾

javascript基础本章简单的介绍在这里,内容并不全面,还请多多见谅。如有错误,请指出。。。。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持PHP中文网!

更多javascript基础知识讲解相关文章请关注PHP中文网!


Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal