JavaScript学习

简介

https://zhuanlan.zhihu.com/p/531318329

JavaScript 组成:核心(ECMAScript) + 文档对象模型(DOM) + 浏览器对象模型(BOM)

位于前端的核心,主要用来操控和重新调整DOM树,通过修改DOM结构 来达到修改页面效果的目的。

ECMAScript 规定了以下内容:
语法、类型、语句、关键字、保留字、操作符、对象。
ECMAScript 就是对实现该标准规定的各个方面内容的语言描述。

DOM——针对XML 但将扩展用于HTML的应用程序编程接口(API)。
DOM把整个页面映射为一个多层节点结构,页面中的每个组成部分都是某种类型的节点,这些节点又包含着不同类型的数据。
借助 DOM 提供的 API,可以轻松自如地删除、添加、替换、修改任何节点。

BOM —— 可以访问和操作浏览器对象模型。
根本上讲,BOM 只处理浏览器窗口和框架,但习惯上把所有针对浏览器的 JavaScript 扩展都算作 BOM 的一部分。如:
弹出新浏览器窗口;
移动、缩放和关闭浏览器窗口的功能;

  1. 提供浏览器详细信息的 navigator 对象;
  2. 提供浏览器所加载页面的详细信息的 location 对象;
  3. 提供用户显示器分辨率详细信息的 screen 对象;
  4. 对 cookies 的支持;
  5. 像 XMLHttpRequest 和 IE 的 ActiveXObject 这样的自定义对象。

在 HTML 中使用 JavaScript

<script>元素

  1. src 属性:可选,当加载外部 js 文件时,此属性必需;可以指向当前页面所在域之外的某个域中的完整 URL 。
  2. type 属性:可选,写代码使用的脚本语言的内容类型,默认 text/javascript。
  3. async 属性: 可选,立即下载脚本,但不应妨碍页面中的其他操作,如下载其他资源或等待加载其他脚本。只对外部脚本文件有效。
  4. defer 属性:可选。立即下载,延迟执行。表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部文件有效。defer=’defer’。

无论如何包含代码,只要不存在 defer 和 async 属性,浏览器都会按照<script>元素在页面中出现的先后顺序对他们依次进行解析。

undefined和null

1、定义

  • (1)undefined:是所有没有赋值变量的默认值,自动赋值。
  • (2)null:主动释放一个变量引用的对象,表示一个变量不再指向任何对象地址。

2、何时使用null?

当使用完一个比较大的对象时,需要对其进行释放内存时,设置为 null。

DOM

getElementsByTagName 和 getElementsByClassName 这两个方法查找多个 dom 元素,返回的是 htmlcollection 类型,是伪数组而不是真数组,故不能使用数组的方法。

我们可以使用数组原型配合 slice 方法,利用 call,apply,bind 方法将伪数组转为真数组。

var x=document.getElementById("main");
var y=x.getElementsByTagName("p");
console.log(y)//在控制台我们可以看到原型proto为htmlcollection,是伪数组
//伪数组转为真数组方法1
console.log(Array.prototype.slice.call(y))//在控制台我们可以看到原型proto为Array(0),是真数组

//伪数组转为真数组方法2
console.log(Array.prototype.slice.apply(y))//在控制台我们可以看到原型proto为Array(0),是真数组

//伪数组转为真数组方法3
console.log(Array.prototype.slice.bind(y)())//在控制台我们可以看到原型proto为Array(0),是真数组

Prototype

通常使用构造器(函数体)定义属性,使用原型对象(prototype)定义方法。

如此,构造器只包含属性定义,而方法则分装在不同的代码块,使代码更具可读性

三个js语法

1.一个全局变量是在全局作用域被声明的变量,对于其它所有的作用域可见。在javascript中,全局变量是全局对象的一个属性。这个全局对象在node中是global , 在浏览器中是window,也就是说

var a=6;
//=== window.a=6

2.this的指向完全取决于函数调用的位置

3.在node(指在js文件)中,顶层作用域中在函数外的 this 指向的是module.exports,在函数内(若函数未绑定特定对象),则this指向的是global

而node在执行一个js文件,是将该js文件当作一个模块,而模块在node中大体是这样运行的

function Module(){
     this.exports={}
}
function Fun(exports, require,module,__filename,__dirname){
//你的在js中的代码
}
var module=new Module();
var exports=module.exports;
var options = [exports, require, module, filename, dirname];
Fun.apply(exports,options);

现在来看,答案已经非常明显啦,在浏览器和node repl中,运行foo()时候的this指向的是全局对象,而你在运行foo()的前一句var bar=2实际上已经在全局对象上添加了一个bar的属性,而且值为2.

而在node执行js文件时,把它当作一个模块,var bar=2中的bar只是顶层作用域的变量,而非全局变量,自然不会在全局对象global上添加一个bar的属性,故为undefined

转载:https://juejin.cn/post/6844904136161361933#1

变量类型

==与===

==的判断

  • 并不是那么严谨的判断左右两端是否相等
  • 它会优先对比数据的类型是否一致
  • 不一致则进行隐式转换,一致则判断值的大小,得出结果
  • 继续判断两个类型是否为null与undefined,如果是则返回true
  • 接着判断是否为string与number,如果是把string转换为number再对比大小
  • 判断其中一方是否为boolean,如果是就转为number再进一步判断
  • 判断一方是否为object,另一方为string、number、symbol,如果是则把object转为原始类型再判断

比较情况

  1. 数组 == 值,(值类型指的是原始类型)会先转成数值再比较,与字符串比较会先转成字符串再比较
  2. 引用 == 值,会把引用类型转成原始类型再比较
  3. 值 == 值,直接比较类型再比较值的大小
  4. 字符串 == 数字,则把字符串转为数值再比较
  5. 其他类型 == boolean,则把boolean转成数值再进一步比较
  6. undefined == null,也会发生隐式转换,且2者可以相互转换,即2者相等,与自身也相等
  7. 对象 == 非对象,如果非对象为string或number,则返回ToPrimitive(对象) == 非对象,的结果;ToPrimitive方法的参数如果是原始类型则直接返回;如果是对象,则调用valueOf方法,如果是原始值再进行原始类型转换和大小对比;如果不是原始值则调用toString,且结果为原始值则进行原始类型比较,如果不是原始值则抛出错误
// 以下结果都为true
console.log([5]==5,['5']==5)
console.log({name:'5'}=='[object Object]')
console.log('5'==5,true==1,false==0)
console.log(undefined==null)
console.log([5,6]=='5,6',['5','6']=='5,6')

大白话:优先比较类型,同类型,比大小,非原始,调ToPrimitive,为对象调valueOf,还非原始调toString,最后还非原始则报错,如果为原始则进行类型对比,如果不同类型再转换,之后对比大小。

优先比类型,再比null与undefined,再比string和number,再比boolean与any,再比object与string、number、symbol;以上如果转为原始类型比较,则进行类型转换,直到类型相同再比较值的大小。

JavaScript中数组迭代方法

forEach

让数组中的每一项做一件事

//我们先用它来遍历数组
  let arry=[9,8,7,6,5,4]
  array.forEach(function(value,index,arr){
      console.log(value)
  }) //输出结果为9 8 7 6 5 4//尝试遍历对象
   let obj={a:1,b:2,c:3,d:4}
   obj.forEach(function(value,index,oObj){
       console.log(value)
   } //输出结果会是obj.forEach is not a function, 
     //所以forEach不可以遍历对象,这也是它和for in的一个区别

一般用于对数组的遍历,不用于对对象的遍历,此方法会对数组中的每一个值进行遍历,直至全部遍历完成。故在其中的return,break会失效。

for in

一般用于遍历对象,循环遍历对象的key,不推荐遍历数组。fot in循环里面的index是string类型的

缺点:某些情况下,会出现随机顺序的遍历,因为里面的值是string类型,所以 增加了转换过程,因此开销较大

   let person={name:"老王",age:23,city:"大唐"}
   let text=""
   for (let i in person){
      text+=person[i]
   }
   输出结果为:老王23大唐 //其次在尝试一些数组
   let arry=[1,2,3,4,5] for (let i in arry){
        console.log(arry[i])
    } //能输出出来,证明也是可以的

for of

可遍历map,object,array,set string等,与forEach不同的是,它可以正常的响应break, return,continue,避免了for in的所有缺点

缺点:不适用于处理原有的原生对象(原生对象是一个子集,包含一些在运动过程中动态创建的对象)

//遍历数组
   let arr=["nick","freddy","mike","james"]; for (let item of arr){
        console.log(item)
    } //暑促结果为nice freddy mike james//遍历对象
   let person={name:"老王",age:23,city:"唐山"} for (let item of person){
        console.log(item)
    } //我们发现它是不可以的

map

让数组通过某种计算产生一个新数组

var newArr = arr.map(function(item,index){
    return item * 2
});

filter

筛选出数组中符合条件的项,组成新数组

var newArr = arr.map(function(item,index){
    return item > 3
});

reduce

让数组中的前项和后项做某种计算,并累计最终值

var result = arr.reduce(function(prev,next){
    return prev + next;
})

every

检测数组中的每一项是否符合条件

var result = arr.every(function(item,index){
    return item > 0;
})

some

检测数组中是否有至少一个项符合条件

var result = arr.some(function(item,index){
    return item > 1;
})

Apply

call和apply的区别

不同之处是:

call() 方法分别接受参数。

apply() 方法接受数组形式的参数。

如果要使用数组而不是参数列表,则 apply() 方法非常方便。

var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"Bill",
  lastName: "Gates"
}
person.fullName.apply(person1, ["Oslo", "Norway"]);
var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"Bill",
  lastName: "Gates"
}
person.fullName.call(person1, "Oslo", "Norway");

在数组上模拟 max 方法

Math.max.apply(null, [1,2,3]); // 也会返回 3

第一个参数(null)无关紧要。在本例中未使用它。


   转载规则


《JavaScript学习》 锦泉 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录