小计
1.script标签的同步异步加载
- async(异步) 表示应该立即开始下载脚本,但不能阻止其他页面动作,比如下载资源或者等待其他脚本加载。只对外部文件有效
<script async src="script.js"></script>
- defer(同步) 表示在文档解析和显示完成后再去执行脚本,只对外部文档有效
<script defer src="script.js"></script>
如果什么都没有写,默认是同步方式
2.严格模式
ECMAScript5增加了严格模式的概念。我们只需要在脚本的第一句话添加一行代码,就开启了严格模式:
" use strict ";
当然也可以给单独的函数设置在严格模式下执行:
function doSmoething(){
" use strict ";
// 函数体
}
JavaScript的严格模式是 ECMAScript 5 引入的一种执行模式,可以通过在代码顶部添加'use strict';
来开启。
严格模式的主要目的是使JavaScript更加严谨和安全,因此它会禁用不安全或可能引起错误的语言特性,提高代码的质量和性能。
以下是严格模式的主要特点和作用:
- 剔除不安全或不推荐使用的JavaScript语言特性,例如强制声明变量,防止意外的全局变量声明。
- 禁止使用
with
语句。 - 消除
eval()
中创建的变量污染全局变量的问题。 - 禁止删除不可删除的属性。
- 禁止函数参数重名。
- 禁止八进制表示法。
- 显示
NaN
和Infinity
的错误信息,而不是经常产生混淆的静默错误。 - 严格模式下的
this
关键字更加明确,不再可以使用默认绑定规则。 - 严格模式下对于一些
Object
的方法变得更加严谨,例如Object.preventExtensions()
、Object.seal()
和Object.freeze()
。
使用严格模式可以避免一些常见的编程错误,并且可以使JavaScript引擎对代码进行更高效的优化,提高代码的性能。
3.变量声明
- var声明变量
- 对同一个变量可以声明多次
- 存在变量提升(
声明在函数内的变量会提升到当前作用域的最顶端
) - 可以声明后不赋值(默认是
undefined
) - 使用var声明的变量默认会成为window对象的属性
- let声明变量
- let声明的变量只在
块级作用域中生效
if(true){
var name = 'matt'
console.log(name) // matt
}
console.log(name) // matt
if(true){
let age = 24
console.log(age) // 24
}
console.log(age) // 报错
- let声明的变量可以不用初始化(let a;)
let声明的变量存在暂时性死区
console.log(age) // 报错 age没有被定义
let age = 24
这是因为使用let声明的变量存在暂时性死区,在解析代码的时候,JavaScript引擎会注意出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量。在let声明之前的执行瞬间被称为“暂时性死区”
通俗易懂的来说就是:使用let声明变量在定义之前都是访问不到这个变量的,我们把这个区域称为暂时性死区
- 使用let声明的变量不会挂载window对象上
- for循环上的let声明
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
// 输出 5 5 5 5 5
for (let i = 0; i < 5; i++ ) {
setTimeout(function() {
console.log(i);
}, 1000);
}
// 输出 0 1 2 3 4
- const声明变量
- const 声明基础类型为常量不允许被修改
- const声明必须赋值且不允许重复声明
补充:在JavaScript中,基础数据类型的数据(如数字,字符串,布尔值,null,undefined)是直接存放在栈内存中的,而引用数据类型(如对象,数组,函数等)则是存储在堆内存中的,栈内存中存放的是该对象内存中的引用地址
我们在声明变量的时候,尽量使用const,其次是let。因为使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。只有我们知道未来会修改时,在使用let。
而在vue中,当我们是使用const创建一个ref的变量时,这个变量时可以被修改的,原因是使用ref创建的变量,本身是一个带有value属性的对象
例如:
const name = ref('张三')
name.value = '李四'
4.判断数据类型
- typeof 操作符
let message = "zhong guo"
console.log(typeof message) // "String"
console.log(typeof (message)) // "String"
console.log(typeof 75) // "Number"
"undefined" // 未定义
"boolean" // 值为布尔值
"string" // 值为字符串
"number" // 值为数字
"object" // 值为对象(不是函数)或者null
"function" // 值为函数
"symbol" 值为符号
- Object.prototype.toString.call()方法
Object.prototype.toString.call() 可以返回一个值类型字符串,比typeof更加精准特别对于复杂类型如:数组、Set,Map,WeakMap, Promise 等,通常用来精确检测类型.
console.log(Object.prototype.toString.call("hello")); // 输出 [object String]
console.log(Object.prototype.toString.call(123)); // 输出 [object Number]
console.log(Object.prototype.toString.call(true)); // 输出 [object Boolean]
console.log(Object.prototype.toString.call(undefined)); // 输出 [object Undefined]
console.log(Object.prototype.toString.call(null)); // 输出 [object Null]
console.log(Object.prototype.toString.call({})); // 输出 [object Object]
console.log(Object.prototype.toString.call([])); // 输出 [object Array]
console.log(Object.prototype.toString.call(function(){})); // 输出 [object Function]
console.log(Object.prototype.toString.call(new Date())); // 输出 [object Date]
console.log(Object.prototype.toString.call(/123/)); // 输出 [object RegExp]
console.log(Object.prototype.toString.call(new Uint8Array())); // 输出 [object Uint8Array]
- instanceof方法
instanceof 可以用来判断一个对象是否是某个构造函数创建的实例。如果是,返回 true,否则返回 false
const arr = [];
console.log(arr instanceof Array); // 输出 true
console.log(arr instanceof Object); // 输出 true
const obj = {};
console.log(obj instanceof Object); // 输出 true
function Person(name) {
this.name = name;
}
const p = new Person("张三");
console.log(p instanceof Person); // 输出 true
console.log(p instanceof Object); // 输出 true
- constructor属性
在 JavaScript 中,每个对象都有一个 constructor 属性,指向该对象的构造函数。通过检查这个属性可以得到一个对象是哪种类型。
console.log("hello".constructor === String); // 输出 true
console.log((123).constructor === Number); // 输出 true
console.log(true.constructor === Boolean); // 输出