一、普通对象

js中的普通对象:无序的键值对集合。

  • 由大括号包裹起来的{key: value}
  • 由零到多组属性名和属性值(键值对)组成。属性名可以是数字、字母、或者下划线等,并且属性名都是字符串类型的。

属性是用来描述当前对象特征的,属性名是当前对象具备的特征,属性值是这个特征的描述,一组属性名和属性值成为一组键值对

声明对象

  1. var feTraining = {
  2. name: '珠峰培训',
  3. age: 9,
  4. characters: '专注前端10年',
  5. 9: 'age'
  6. }

对象的操作:键值对的增删改查

  • 获取对象的某个属性的值
    • 对象.属性名
    • 对象[‘属性名’]
  1. console.log(feTraining.name);
  2. console.log(feTraining['name']);
  3. var str = 'age';
  4. console.log(feTraining[str]); // 9

如果用. 后面的属性名不用写引号,如果使用[],属性名需要用字符串包裹 如果属性名是数字,只能使用 [] 方括号里面还可以写变量或者表达式 如果获取一个对象不存在的属性,会得到一个 undefined

  • 增加/修改
    js 对象中的属性名是不允许重复的,是唯一的
    如给一个对象的属性赋值,有两种情况:
    • 如果对象之前不存在这个属性,那么就是给这个对象增加一个属性,值是等号右侧的值
    • 如果对象之前已经存在这个属性了,再赋值就是修改对象中的这个属性的值
  1. feTraining.courses = 'JS高级+vue+react+node'; // feTraining 之前不存在 courses 这个属性,所以是增加;
  2. console.log(feTraining);
  3. feTraining.name = 'Everest Training'; // feTraining 之前就存在 name 属性,所以是修改
  4. console.log(feTraining);
  • 删除

  • 彻底删除:把对象的属性名和属性值都删除。 delete obj[‘name’]

  • 软删除:将对象的某个属性的值赋值为null。 obj.name = null
  1. delete feTraining.age;
  2. console.log(feTraining);
  3. feTraining.courses = null;
  4. console.log(feTraining); // course 属性名还在,只是值为 null 了

思考?

  1. var obj = {
  2. name: '珠峰培训',
  3. age: 10
  4. };
  5. obj.name // '珠峰培训'
  6. obj['name'] // '珠峰培训'
  7. obj[name] ?? => name 'name'有什么区别?'name' 表示的是一个字符串,而 name 表示一个变量名

对象中的属性名都是字符串类型的


二、数组对象

数组是【有序】的键值对集合;但是数组的键是浏览器设置的,不需要我们手动设置,并且键都是从0开始的数字,我们称数字属性名为【索引】。数组的第一项的对应的索引是0,第二项对应的索引是1,以此类推,第n项对应的索引是 n - 1。

var ary = [12, 23]; // ? 12和23是都是属性值,属性名呢?
console.log(ary); // 从控制台可以发现是有键的,并且键都是数字

数组的操作

数组的键是数字,所以只能用方括号的方式获取、修改,而且写在方括号里面的属性名不需要用引号包裹;

  1. var ary = [12, 23];
  2. console.log(ary[0]);
  3. console.log(ary.0); // 报错
  4. console.log(ary[1]);
  5. console.log(ary[2]); // 访问一个数组不存在的索引,会得到一个 undefined

三、基本数据类型和引用数据类型的区别

  1. var a = 12;
  2. var b = a;
  3. b = 13;
  4. console.log(a); // 12
  5. console.log(b); // 13
  6. var obj1 = {
  7. name: '珠峰',
  8. age: 10
  9. };
  10. var obj2 = obj1;
  11. obj2.age = 100;
  12. console.log(obj1.age); // 100
  13. console.log(obj2.age); // 100

为什么会有这种情况?

基本数据类型(也叫做值类型)的操作,直接操作就是这个值,意思就是说变量本身就代表这个值。所以: var b = a; a存储12这个值,然后声明一个变量 b,然后让b = a,就是让b = 12。这样和 var b = 12本质上没有任何区别;

引用数据类型都是存放在堆内存空间中的,同时这个堆内存空间有一个十六进制的内存地址(例如aaafff000)。我们在声明一个变量存储引用数据类型时,不是直接把对象赋值给变量,而是把对象的堆内存地址赋值给变量。所以 obj1 拿到的知识这个堆内存地址 aaafff000;
所以引用数据类型的操作不是直接操作的值,而是操作它的引用数据类型的堆内存地址。所以var obj2 = obj1; 只是把 obj1 代表的堆内存地址赋值给了变量 obj2。
所以 obj2.age = 100;是通过 obj2 的堆内存地址找到堆内存地址中的存储的 age 的值,把它修改成100。同时,我们访问 obj1.age 时也是先通过 obj1 存储的堆内存地址找到内存空间,然后从里面把属性age的值取到,此时这个内存空间中的值已经修改成100了。所以obj.age 也是100

四、布尔类型、布尔运算

布尔类型值只有两个值,true 和 false;布尔运算用来测试真假值,即运算结果是真的还是假的,通常结合 js 的判断语句(if/switch-case/三元表达式)使用。

其他数据类型和布尔值进行转换

  • Boolean方法

语法:Boolean(需要转换的值) ;得到转换后的规则

  1. var boo = Boolean(1);
  2. var boo2 = Boolean(0);
  3. console.log(boo, boo2); // true false
  • !运算符(取反运算符)true 取反就是 false,而 false 取反就是 true

运算符是有固定功能的关键字或者符号。它通过操作值也可以得到返回结果,与方法不同的是运算符不需要小括号。 语法:!需要取反的值 ;得到取反后的布尔值。其内部机制是先把其他数据类型转换成布尔值,然后再取反。 转换规律:在 js 中只有 0/NaN/空字符串’’/null/undefined 这5个值转换成布尔值是 false,其余的都是 true。

  1. var str = '珠峰培训,10年专注前端';
  2. var result = !str;
  3. // 内部运作机制:
  4. // 第一步先将str转换成布尔值,str不属于那5个值,所以 Boolean(str) => true
  5. // 然后再取反,true 取反 => false
  6. console.log(result); // false
  • !! 运算符 等效于 Boolean 方法

语法:!!需要转换的值;

  1. var num1 = !!1;
  2. var num2 = !!0;
  3. console.log(num1, num2); // true false
  4. console.log(!!{}); // true
  5. console.log(!![]); // true
  6. console.log(!!{name: 'zhufeng'}); // true

五、null 和 undefined

null 空对象指针;不占内存,通俗理解就是人为的手动先赋值为 null,后面程序中我们会再给它赋值为其他值;

undefined 未定义。多数情况是某些浏览器内置机制设置的默认值,声明一个变量不赋值,这个变量的默认值就是undefined


六、js中的判断语句

判断语句是流程控制的重要语句,其作用是当满足某些条件时才能执行某些代码

1、if/else if/else

  1. // 单独使用if
  2. if (条件) {
  3. // 浏览器会对条件进行布尔运算,即求出条件时 true 还是 false。条件为 true 时,即条件成立的时候才会执行这个花括号里面的代码
  4. }
  5. // 两种情况,结合 else
  6. if (条件) {
  7. // 条件为 true 时
  8. } else {
  9. // 不满足条件的时候要执行的代码
  10. }
  11. // 多种情况,结合 else if
  12. if (条件1) {
  13. // 条件1为 true 时
  14. } else if (条件2) {
  15. // 条件2为 true 的时候要执行的代码
  16. } else {
  17. // 上面条件都不满足条件的时候要执行的代码
  18. }

示例:

  1. var num = 6;
  2. if (num > 6) {
  3. num++; // => num = num + 1; 在自身上累加一个
  4. } else if (num >= 10) {
  5. num--;
  6. } else {
  7. num+=2
  8. }
  9. console.log(num);

只要有一个条件成立,后面不管是否还有成立的条件,都不会在执行了

  1. var num = 10;
  2. if (num > 5) {
  3. num += 2;
  4. } else if (num > 8) {
  5. // 虽然 num 满足大于8,但是再上面已经执行过num>5的代码,所以这里不会执行
  6. num += 3;
  7. } else {
  8. num += 4;
  9. }
  10. console.log(num); // 12

2、条件怎么写?

if (条件) 条件最终需要的是一个布尔值,然后根据是 true 还是 false 来判断条件是否成立。如果条件里面写的是可以返回布尔值的表达式,那么就利用这个表达式的返回结果;如果不是返回布尔值,那么浏览器会自动把它转换成布尔值,然后用转换出来的结果判断条件是否成成立

常见比较运算符:比较运算符都会返回布尔值

  • 大于(>), a > b, 当 a 大于 b 时返回 true,否则返回 false
  • 大于等于(>=), a >= b ,当 a 大于等于 b 时返回 true,否则返回 false
  • 小于(<),a < b
  • 小于等于(<=)
  • 不等于(!=)、
  • 等于(相对比较== 或者 绝对比较===)
    • == 是相对比较,只要两边的值相同就行,不比较类型,如 1 == ‘1’ 返回 true
    • === 是绝对比较,两边值相同还不够,还要比较类型。1 === ‘1’ 返回 false,因为1是 number,而’1’是 string,类型不同
  1. console.log(1 > 0); // true
  2. console.log(1 < 0); // false
  3. console.log(1 == '1'); // true
  4. console.log(1 === '1'); // false

条件常见形式:

  • 使用比较运算符,直接返回布尔值
  • 如果是数学表达式,那么会先运算求值,然后再把运算出来的结果转换成布尔值。

在js中,+ - * / % 都是数学运算,除 + 以外,其余的运算符在运算时,如果遇到非数字类型的值,首先会转成数字类型(Number),然后再进行运算

  1. if ('3px' + 3) {
  2. // + 操作符在两边都是数字时才是加法运算符,如果有一个不是数字,那么加好就是字符串拼接。
  3. // 所以 '3px' + 3的结果是字符串'3px3',而字符串 '3px3'转换成布尔值以后是true,所以条件成立
  4. }
  5. if ('3px' - 3) {
  6. // - 会调用Number()方法把'3px'转成数字,Number('3px') -> NaN,而NaN - 3 -> NaN,而NaN转成布尔值是false,所以条件不成立
  7. }
  • 其他情况,均会把条件转成布尔值。

练习

  1. var num = parseInt('width: 35.5px');
  2. if (num == 35.5) {
  3. alert(0);
  4. } else if (num == 35) {
  5. alert(1);
  6. } else if (num == NaN) {
  7. alert(2);
  8. } else if (typeof num == 'number') {
  9. alert(3);
  10. } else {
  11. alert(4);
  12. }

2、三元运算符

语法: 条件 ? 成立要做的事情 : 不成立要做的事情 相当于简单的 if else判断 并且三元运算符是有返回值的,当条件成立时三元运算符返回条件成立时的值,不成立时返回不成立的值。

  • 一般情况
  1. var num = 12;
  2. if (num < 10) {
  3. num++;
  4. } else {
  5. num--;
  6. }
  7. // 改写成三元运算符
  8. num > 10 ? num++ : num--;
  • 特殊情况:
    • 如果三元运算符中条件成立或者不成立时不需要任何操作,我们用null/undefined/ void 0占位
  1. // num > 10就++,否则啥也不做
  2. num > 10 ? num++ : null;
  3. num > 10 ? num++ : undefined;
  4. num > 10 ? num++ : void 0;
  1. - 如果在条件成立(或不成立)时有多条语句,需要用小括号括起来,每条语句;
  1. var num = 10;
  2. num >= 10 ? (num++, num*=2) : null;

3、switch case

语法:

  1. switch (变量或者表达式) {
  2. case 1:
  3. 变量或者表达式的值是值1的时候执行的代码;
  4. break;
  5. case 2:
  6. 变量或者表达式的值是值2的时候执行的代码;
  7. break;
  8. ...
  9. case n:
  10. 变量或者表达式的值是值1的时候执行的代码;
  11. break;
  12. default:
  13. 以上情况都不满足时,相当于else
  14. }

switch case应用于变量(表达式)在不同值的情况下的不同操作,每一种 case 结束后都需要加break(break是结束整个判断);

  1. var num = 12;
  2. if (num == 10) {
  3. num++;
  4. } else if (num == 5) {
  5. num--;
  6. } else {
  7. num = 0;
  8. }
  9. // 改写成 switch case
  10. switch (num) {
  11. case 10:
  12. num++;
  13. break;
  14. case 5:
  15. num--;
  16. break;
  17. default:
  18. num = 0;
  19. }

注意:switch case 中每一个 case 的比较都是基于 === 绝对相等来完成判断的。即 10 === ‘10’ 是 false。真实项目中常用绝对比较。