- 基本类型值(值类型) VS 引用类型值
var n=10;var m=n;m=20;console.log(n); //=>10var a={name:'珠峰'};var b=a;b.name='培训';console.log(a.name); //=>'培训'
var n=[12,23,34];var m=n;m[0]=100;m=[100];n[1]=200;console.log(n,m);//=>n:[100,200,34] m:[100]
var obj={n:10,m:obj.n*10};console.log(obj.m);
====
创建变量并且赋值的详细操作步骤
例如:var n = 10;
- 变量提升阶段(js代码执行之前),第一步先把n这个变量声明 var n;(默认值undefined)
- 开辟一个位置或者空间,把值存储起来
- 让变量和值关联在一起(基于等号完成赋值),我们把赋值关联这一步称之为“变量的定义”
注意点:
- 当我们的值还没有彻底准备完成之前,值和变量是没有关系的
====
【基本类型操作机制 =>值类型】
值类型操作都是“按照值来操作的”
- 赋值的时候,也是直接的把这个值赋值给变量(或者说和变量关联)
- 一个变量把自己的值赋值给另外一个变量的时候,也是重新开辟一个新的位置,把原有变量存储的值放到新位置一份(新老位置各有相同的值,但是是独立分开的,没有关联),在把新位置上的值赋值给新变量
- …
====
【引用数据类型】
引用数据类型,操作的时候,都是按照“空间的引用地址来操作的”
- 首先不能像基本基本值一样在作用域中开辟位置存储,需要额外单独开辟一个新的空间(有一个16进制的地址,通过地址可以找到空间)
- 对于对象数据类型来说,它会把自己本身的键值对依次存储到这个空间中(对于函数来说,在空间中存储的是函数体中的代码字符串)
- 引用类型是按照引用地址来操作的,所以给变量赋的值是空间的地址,而不是对象本身,以后的操作都是通过地址找到空间然后再操作
====
【堆占内存】
在JS中有两个重要的内存:堆内存/栈内存
- 栈内存
- 提供代码执行的环境
- 基本类型值都是直接的存储在栈内存中的
- 堆内存
- 引用类型值都存储在堆内存中
===========================
二、DOM操作
在JS中通过一系列属性和方法,可以操作页面中的元素标签等
- 想要操作谁,就先获取谁
- 按照自己的需求,使用对应的API(提供的属性和方法)操作即可
【获取元素】document.getElementById:在整个文档中,通过ID获取到指定的元素对象(这里document是限定了获取元素的范围,我们把它称为执行上下文(context))
[context].getElementsByTagName:在指定的上下文中,通过标签名获取一组元素(获取的一组元素称之为 元素集合(HTMLCollection))
====================
三、ECMAScript中的操作语句
【判断语句】
- if / else if / else
var n = parseFloat('width:15.5px'); //=>NaNif(n==15){console.log(1);}else if(n==15.5){console.log(2);}else if(n==NaN){ //=>NaN!=NaNconsole.log(3);}else if(typeof n=='number'){ //=>typeof NaN : "number"console.log(4);}else{console.log(5);}
- 三元运算符
处理简单的if/else
var n=10;if(n>=10){n++; //<=>n=n+1 n+=1 自身累加1}else{n--;}//=>改写成三元运算符n>=10?n++:n--;//=====================var m=10;if(m>=10){m++;console.log(m);}m>=10?(num++,console.log(m)):null;如果某一部分不需要做任何的事情,我们不写东西,语法不符合,我们可以使用null/udnefined/void 0来占位即可如果某部分需要做多件事情,我们用小括号包裹起来,每一句中间用逗号分隔即可
思考题:
var n=10;if(n>=0){if(n<=10){n++;}else{n--;}}else{if(n<=-10){n++;}}回去后改写成三元运算符
- switch case
应用于一个变量在不同值情况下的不同操作
var n=10;if(n==5){n++;}else if(n==10){n+=2;}else{n+=3;}//=>改写switch(n){case 5:n++;break; //=>当前情况成立,结束判断,不在向下找case 10:n+=2;break;default:n+=3;}
每一种CASE情况的比较都是基于“===”绝对相等完成的
'10'==10 =>true 相等比较,不严格,如果等号两边的数据类型不相同,则转换为相同的在进行比较'10'===10 =>false 绝对相等,一定要保证类型和值都相等才可以,类型不一样,不会转换,直接不等
======
数学运算符:+ - * / %(取余)
在JS中“+”有特殊的含义,其它运算符都是数学运算(如果操作的值不是数字,也会先转换为数字,然后在运算)
'3'-1 =>2'3px'-1 =>NaN
“+”在JS中不仅仅是数学运算,也有字符串拼接的效果(只要运算中出现字符串,就是字符串拼接,否则就是数学运算)
3+1 =>4'3'+1 =>'31''3px'+1 =>'3px1'
【循环语句】
- for循环:在JS中如果我们想按照一定的规律重复去做某件事情,则需要使用循环
var ary = [12,23,34,45];//=>需求:获取数组中的每一项(数组长度不固定)for(var i=0;i<ary.length;i++){console.log(ary[i]);}/** i=0 i<4 第一轮循环* console.log(ary[0]);* i++ -> i=1* i=1 i<4 第二轮循环* console.log(ary[1]);* i++ -> i=2* ...* i=4 i<4 循环结束*/
任务:回去后自己查询(建议百度搜索、也可以看视频)break和continue在for循环中的作用和细节问题
==================================
四:ECMAScript中的函数(function)
函数:一个方法,基于方法可以实现一些功能 函数诞生的目的在于“封装”:把实现功能的代码封装到一个函数中,以后再想实现这个功能,不需要重新编写代码,只需要执行函数即可,这样降低了页面中的冗余代码,提高了代码的重复利用率(“低耦合高内聚”)
function 函数名([形参]){函数体:实现功能的JS代码}函数名([实参]);
//=>创建函数function fn() {var n = Math.PI;n *= 100;n = n.toFixed(2);console.log(n);}//=>执行函数fn();fn();fn();...
函数的运作机制:
【创建函数】
- 函数也是引用类型值,首先开辟一个新的堆内存(16进制地址)
- 把函数体中实现功能的代码“当做字符串”存储到堆内存中
- 把堆内存的引用地址赋值给函数名(变量名)
【执行函数】
目的:把函数体中的JS代码执行,以此实现具体的功能和需求
- 首先开辟一个新的栈内存(私有作用域),提供JS代码执行赖以生存的环境
- 把原有在堆内存中存储的“字符串”,拿过来,放到新的栈内存中,变为真正的JS代码,自上而下执行
====
封装一个函数实现一些功能,有时候发现实现功能的原材料不足,需要执行函数的时候传递给我们才可以,此时我们可以给函数设置几个入口,我们把函数的入口称之为:“形参变量”(入口是变量)
//=>创建一个函数实现两个数求和function sum(n,m){//=>n/m就是形参入口,也是两个变量var total=0;total=n+m;console.log(total);}//=>执行函数sum(10,20); //=>传递的值是实参(实参是传递给形参变量的具体值) n:10 m:20sum(10); //=>n:10 m:undefined 设置了形参,执行的时候不传递值,默认值是undefinedsum(10,20,30); //=>n:10 m:20
