js的再学习
js中的操作语句:判断,循环
判断
条件成立做什么?不成立做什么
- if/else
// if里面的条件可以有多样性,但是我们不论怎么写,最终都会自动调用 Boolean()转换函数将这个表达式的结果转换为一个布尔值 if (条件) { // 做的事件 } else if (条件) { // 做的事件 } else { // 上面条件都不成立做的事件 }
- 三元表达式
// 简单的if/else形式 // 语法: 条件?成立时的处理:不成立时的处理 let a = 10; a>0?xxx:xxxx // 如果处理的事件比较多,我们用括号包起来,每一件事件用逗号分隔 a>0?(xxx,bbb):(xxx,bb) // 如果不处理事件的话,可以使用null/undefined占位 a>0?xxx:null // 我们可以在三元表达式中嵌套三元表达式 a>0?(a<10?a++:a--):(a>-10?a+=2:null)
- swith case
- swith中的case判断的时候,判断等于的时候是使用 全等 ,if()的话使用的是 ==
// 一个变量在不同的值情况下的不同操作 let a = 10; swith(a){ case 1: 事件; break; case 10: 事件; break; default: 事件; } // 每一个case后,我们需要有一个break结束语句,如果没有的话 会进入下一个case,default表示所有条件都不成立的事件
- ==for in ==
- for in 用来遍历对象中的键值对的(continue和break同样适用)
- continue 立即退出这一次循环,从循环顶部继续执行
- break 退出循环体,执行循环后面的语句
var obj = { name:'xxx', age:23, grade:2, 1:'111', 2:'222' } for (var key in ojb){ // 循环中key,对象中的属性名 } // for in 循环的时候,优先遍历数字属性名
操作符
逻辑非
- 逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反。逻辑非操作符遵循下列规则
- 如果操作数是一个对象,返回 false;
- 如果操作数是一个空字符串,返回 true;
- 如果操作数是一个非空字符串,返回 false;
- 如果操作数是数值 0,返回 true;
- 如果操作数是任意非 0 数值(包括 Infinity),返回 false;
- 如果操作数是 null,返回 true;
- 如果操作数是 NaN,返回 true;
- 如果操作数是 undefined,返回 true。
逻辑与
- 逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值。在有一个操作数不是布尔值的情况
下,逻辑与操作就不一定返回布尔值。它遵循下列规则:- 如果第一个操作数是对象,则返回第二个操作数;
- 如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回该
对象; - 如果两个操作数都是对象,则返回第二个操作数;
- 如果有一个操作数是 null,则返回 null;
- 如果有一个操作数是 NaN,则返回 NaN;
- 如果有一个操作数是 undefined,则返回 undefined。
逻辑或
- 与逻辑与操作相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值;此时,它遵循下
列规则:- 如果第一个操作数是对象,则返回第一个操作数;
- 如果第一个操作数的求值结果为 false,则返回第二个操作数;
- 如果两个操作数都是对象,则返回第一个操作数;
- 如果两个操作数都是 null,则返回 null;
- 如果两个操作数都是 NaN,则返回 NaN;
- 如果两个操作数都是 undefined,则返回 undefined
四则运算
- 加
- 如果两个操作符都是数值,执行常规的加法计算
- 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;
- 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接 起来。
- 如果有一个操作数是对象、数值或布尔值,则调用它们的 toString()方法取得相应的字符串值, 然后再应用前面关于字符串的规则
- 注意以下情况
let a = '10'; a++; // 11 ++ 和-- 是纯粹的数学运算,先转为number再进行加减 let b = '10'; a = a+1; // "101" 字符串
- 注意++i和i++
let i =1; 5+(++i) // 7 let b =1; 5+(i++) // 6
- 减
- 乘
- 除
垃圾回收
- 标记清除
- 垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方
式)。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记
的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器
完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。
- 垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方
- 引用计数
- 当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是 1。
如果同一个值又被赋给另一个变量,则该值的引用次数加 1。相反,如果包含对这个值引用的变量又取
得了另外一个值,则这个值的引用次数减 1。当这个值的引用次数变成 0 时,则说明没有办法再访问这
个值了,因而就可以将其占用的内存空间回收回来
- 当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是 1。
浏览器的常用输出方法
- 控制台输出
console.log()
输出对象(控制台)console.dir()
输出一个键值对的详细信息(控制台)console.table()
把一个多维数组按照表格的形式输出到控制台
- 浏览器窗口弹窗
alert()
要在 window 上弹出的对话框中显示的纯文本(而非 HTML 文本)confim
confirm() 方法用于显示一个带有指定消息和 OK 及取消按钮的对话框。prompt
prompt() 方法用于显示可提示用户进行输入的对话框
把script标签放在头部和尾部的区别
- 放在head标签中
- 将script放在里,浏览器解析HTML,发现script标签时,会先下载完所有这些script,再往下解析其他的HTML
- 放在body的底部
- 将script放在尾部的缺点,是浏览器只能先解析完整个HTML页面,再下载JS。而对于一些高度依赖于JS的网页,就会显得慢了
对象
- 在JavaScript中对象
是一组元素的相关属性和方法的集合
- 为什么要用到对象?统一管理多个属性
- 对象的组成:
属性
,方法
- 如何访问对象内部数据:通过
.属性名
或者['属性名']
- 有时不能通过
.属性名
获取数据:比如属性名有特殊字符,属性名为变量var a = {} // a.content-type 这种方式不能使用.属性名设置数据 // 要通过下面 a['content-type'] = 'text/json' 还有一种 var a = "age" var b = {age:18} b.a // 不能获取age的值,要通过 b[a] // 18获取
- 有时不能通过
函数
- 什么是函数:
实现特定功能的代码段的封装体,只有函数是能执行的,其他都不行 - 为什么要用函数
提高代码复用率,便于交流沟通 - 如何定义函数
- 函数声明
function fn1(){ }
- 表达式
var fn2 = function(){}
- 如何调用函数
- 最常见的通过
()
直接调用 - 通过对象调用
obj.test()
- 通过
new test()
- 通过apply和call方式调用:
test.call(obj)
,appl,call方法可以让一个函数成为指定对象的方法进行调用
- 最常见的通过
回调函数
- 什么样的函数是回调函数
- 你定义的
- 你没有调用
- 但是最终执行了
- 常见的回调函数
- dom时间的回调函数
- 定时器回调函数
- ajax请求回调函数
IIFE 立执行函数(自调用函数)
- 作用:隐藏实现,不会污染外部(全局)命名空间,用来编写js模块
(function{
console.log(1)
})()
this是什么
- 任何函数本质上都是通过某个对象调用的,如果没有指定的话就是window
- 所有函数内部都有一个变量this
- 它的值是调用函数的当前对象
如果确定this的值
- 函数 this 的指向取决于当前调用该函数的对象,也就是执行时的对象
this到底是谁
- 全局对象&调用普通函数
- 全局对象:在全局环境中,this 指向全局对象,在浏览器中,它就是 window 对象。下面的示例中,无论是否是在严格模式下,this 都是指向全局对象。
var x = 1 console.log(this.x) // 1 console.log(this.x === x) // true console.log(this === window) // true
- 普通函数:如果普通函数是在全局环境中被调用,在非严格模式下,普通函数中 this 也指向全局对象;如果是在严格模式下,this 将会是 undefined。
- 作为对象方法的调用
- 如果函数作为对象的一个方法时,并且作为对象的一个方法被调用时,函数中的this指向这个上一级对象。(就是谁调用这个函数,this就指向谁)
var x = 1 var obj = { x: 2, fn: function() { console.log(this); console.log(this.x); } } obj.fn()
- 如果函数被多个对象嵌套,this指向:this 始终会指向直接调用函数的上一级对象
var x = 1 var obj = { x: 2, y: { x: 3, fn: function() { console.log(this); // Object {x: 3, fn: function} console.log(this.x); // 3 这里的this是y } } } obj.y.fn();
- 如果函数被多个函数嵌套,嵌套的函数不会从调用它的函数中继承 this,当嵌套函数作为函数调用时,其 this 值在非严格模式下指向全局对象,在严格模式是 undefined
function fn() { console.log(this === obj); // false console.log(this); // Window 全局对象 } var obj = { y: function() { console.log(this === obj); // true console.log(this); // Object {y: function} fn(); } } obj.y();
- 作为构造函数调用
- 我们可以使用 new 关键字,通过构造函数生成一个实例对象。此时,this 便指向这个新对象。
var x = 1; function Fn() { this.x = 2; console.log(this); // Fn {x: 2} } var obj = new Fn(); // obj和Fn(..)调用中的this进行绑定 console.log(obj.x) // 2
- call 和 apply 方法调用
- 如果你想改变 this 的指向,可以使用 call 或 apply 方法。它们的第一个参数都是指定函数运行时其中的this指向。如果第一个参数不传(参数为空)或者传 null 、undefined,默认 this 指向全局对象(非严格模式)或 undefined(严格模式)。
var x = 1 var obj = { x: 2 } function Sum(y, z) { console.log(this.x + y + z) } Sum.call(obj, 3, 4) // 9 Sum.apply(obj, [3, 4]) // 9
- bind 方法调用:
- 调用 f.bind(someObject) 会创建一个与 f 具有相同函数体和作用域的函数,但是在这个新函数中,新函数的 this 会永久的指向 bind 传入的第一个参数,无论这个函数是如何被调用的。
var x = 1 var obj1 = { x: 2 }; var obj2 = { x: 3 }; function fn() { console.log(this); console.log(this.x); }; var a = fn.bind(obj1); var b = a.bind(obj2); fn(); // Window 全局对象 // 1 a(); // Object {x: 2} // 2 b(); // Object {x: 2} // 2 a.call(obj2); // Object {x: 2} // 2 // 在使用bind改变this指向后,通过apply以及call再改变this指向,则无作用
- 箭头函数中this指向:箭头函数没有自己的this绑定。箭头函数中使用的this,其实是直接包含它的那个函数或函数表达式中的this
- 就是说箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。
// 有函数 var obj = { y: function() { console.log(this === obj); // true console.log(this); // Object {y: function} var fn = () => { console.log(this === obj); // true console.log(this); // Object {y: function} } fn(); } } obj.y() // 无函数 var obj = { y: () => { console.log(this === obj); // false console.log(this); // Window 全局对象 var fn = () => { console.log(this === obj); // false console.log(this); // Window 全局对象 } fn(); } } obj.y()