«

笔记-4-JavaScript基础(DOM/BOM)

codeez 发布于 阅读:2057 笔记


JS是一种高级的、解释型的编程语言;
JS是一门基于原型、头等函数的语言,是一门多范式的语言,它支持面向对象程序设计,指令式编程,以及函数式编程。

历史:
1994年,网景公司(Netscape)发布了Navigator浏览器0.9版
这是历史上第一个比较成熟的网络浏览器,但这个版本的浏览器只能浏览,不具备与访问者互动的能力。
网景公司急需一种网页脚本语言,使得浏览器可以与网页互动。
1995年网景公司招募了程序员Brendan Eich 希望将Scheme语言作为网页脚本语言;
就在这时,Sun公司将Oak语言改名为Java,正式向市场推出。Java推出后立马在市场引起轰动,使得网景公司动了心,决定与Sun公司结盟,希望将Java嵌入到网页。Brendan Eich本人热衷于Scheme,并对Java不感兴趣,用10天时间设计出来了JavaScript。
最初这门语言的名字是Mocha(摩卡),在Navigator2.0 beta版本更名为LiveScript,在Navigator2.0 beta 3 版本正式重命名为JavaScript,为了蹭Java的热度。
但是这门语言当时更像是一个多种语言的大杂烩:
借鉴C语言的基本语法;
借鉴Java语言的数据类型和内存管理;
借鉴Scheme语言,将函数提升为一等公民(first class)的地位;
借鉴Self语言,使用基于原型(prototype)的继承机制。
微软公司于1995年首次推出Internet Explorer 从而引发了与Netscape的浏览器大战
微软对Netscape Navigator解释器进行了逆向工程,创建了JScript,与网景公司竞争。
这时候对开发者来说是一场噩耗,因为需要针对不同的浏览器进行适配
1996年11月,网景公司正式向ECMA(欧洲计算机制造商协会)提交语言标准
1997年6月,ECMA以JavaScript语言为基础制定了ECMAScript标准规范ECMA-262
ECMA-262是一份标准,定义了ECMAScript
JavaScript成为了ECMAScript最著名的实现之一
除此之外,ActionScript和JScript也都是ECMAScript规范的实现语言
所以说,ECMAScript是一种规范,而JavaScript是这种规范的一种实现。
1997 - ES1;1998 - ES2; 1999 - ES3; 2009 - ES5; 2015 - ES6


<noscript>元素被用于给不支持javascript的浏览器提供替代内容
<script>元素是双标签元素,在引用外部js文件时,标签内不能再写代码,推荐将元素放置在<body>元素内容底部。

JavaScript代码严格区分大小写
变量命名规则:变量可由字母、下划线、美元符号、数字组成,但不能以数字开头,不能使用关键字、保留字。
多个单词使用小驼峰的方式表示

不使用var 声明变量也可以创建变量,并挂在window对象中,不管在哪个作用域。
var声明的变量只要在全局作用域都会挂到window对象。

语句是向浏览器发出的指令,通常表达一个操作或者行为,每条语句后面通常加分号来表示语句的结束。当存在换行符时,JS会将其理解为隐式的分号,所以也可以省去手动添加的操作。
// 单行注释 , /* 多行注释 *//** 文档注释(不常用)*/
vscode插件推荐:ES7+ react (console.log可通过clg快速生成)
配置方法大括号颜色和连线:Bracket Pairs(控制是否启用括号对指南):active、Bracket Pair Colorization(控制是否启用括号对着色):true

在JavaScript中有8种基本的数据类型(7种原始类型和1种复杂类型)
原始(基本):Number String Boolean Undefined Null BigInt Symbol
复杂(引用):Object

typeof 操作符 用来判断 undefined、boolean、string、number、symbol、function、object(null)
特殊的数值:Infinity 无穷大 , NaN 不是一个数字 , 0x代表16进制 , 0o 开头表示8进制 , 0b 开头表示2进制;
JS中数字可以表示的范围:Number.MAX_VALUE 最大值 , Number.MIN_VALUE
isNaN()方法判断值是否是NaN
当对一个对象类型进行初始化时,不建议初始化为{} 建议初始化为null。{}转换为boolean时是true。
变量声明但没赋值时,它的默认值就是undefined,一般不会主动设置undefined。

可以用Array.isArray()来检测是否是数组,因为typeof 数组会显示object(兼容到IE8)shift、unshift、push、pop方法,unshift是在头添加
splice()方法用于替换数组中的指定项,在指定位置插入,删除指定项。会以数组形式返回被删除的项。
slice()方法用于截取子数组,slice(a,b)从a到b不包含b,不会更改原数组,不提供b的话会截取到最后。
数组的join()方法可以把数组转为字符串、split()方法将字符串转为数组。join的参数是以什么作为连接符,如果留空会默认以逗号分隔。
如同调用toString()
concat()方法合并链接多个数组arr1.concat(arr2,arr3) 就会把1,2,3连起来,不改变原数组
reverse()将数组置反,更改原数组。
indexOf()功能是搜索数组中的元素,并返回位置,不存在返回-1
includes()是判断一个数组是否包含某个值,返回布尔值
sort()数组排序,这个方法的参数是一个函数,函数的参数有a,b 如果需要他们俩交换位置就返回正数,否则返回负数。

冒泡排序:4个数字需要比较三趟,比较3+2+1=6次

显示转换:
其他类型转成字符串类型:String()、toString()
其他类型转成数字类型:Number() undefined -> NaN | null -> 0 | true/false -> 1/0
注意:Boolean("0") // true

算数运算符/赋值运算符/关系(比较)运算符/逻辑运算符
算数运算符:加、减、乘、除、取余,幂(ES7)2 ** 3 = 8 等于 Math.pow(2,3)
算数运算符其他内容:原地修改:+=等等,自增自减:++/--
运算顺序:非运算 > 数学运算 > 关系运算 > 逻辑运算

== 一般会隐式转换成Number类型再比较,null例外。

0 == "" // true
0 == false // true
0 == null // false
0 == undefined // false
null == undefined // true
Number(null) // 0
Number(undefined) // NaN

arguments 是类数组对象,内部包含函数所有传入的实参

递归实现斐波那契数列:

// 数列 1 1 2 3 5 8 13 21 34 55
// 位置 1 2 3 4 5 6  7  8  9  10 第n个数是多少
function fibonacci(n){
if(n === 1 || n === 2) return 1
return fibonacci(n-1) + fibonacci(n-2)
}
console.log(fibonacci(10))

ES6之前没有块级作用域的概念,但函数可以定义自己的作用域
作用域(Scope)表示一些标识符的作用有效范围
函数的作用域表示在函数内部定义的变量,只有在函数内部可以被访问到

函数表达式、匿名函数、高阶函数、回调函数、立即执行函数(IIFE)
闭包是函数本身和该函数声明时所处的环境状态的组合,每次创建函数其实都会创建闭包。他有记忆性和模拟私有变量的特点。当闭包产生时,函数所处环境的状态会始终保存在内存中,不会在外层函数调用后被清除,这就是记忆性。

<body>
    <div class="box">
      <input type="button" value="按钮1" class="btn" />
      <input type="button" value="按钮2" class="btn" />
      <input type="button" value="按钮3" class="btn" />
      <input type="button" value="按钮4" class="btn" />
    </div>
    <script>
      var btns = document.querySelectorAll(".btn");
      for (var i = 0; i < btns.length; i++) {
        (function (m) {
          btns[m].onclick = function () {
            console.log("点击了按钮" + (m + 1));
          };
        })(i);
      }
      // 在没有块级作用域的时候使用闭包来缓存变量i
    </script>
  </body>

chrome调试技巧->Sources,想在哪行停止就点击一下行号,打断点。【在代码中写debugger】也是同样的作用。
右侧公护栏的Watch用来检测某个变量的变化。+ 号 添加要监听的变量。
Breakpoints 是所有断点的列表
Scope 作用域

恢复执行(恢复一个断点的执行)、过掉当前行代码执行下一行、进函数内部、立即跳出函数、最后一个和第三个的区别是不会进入异步函数

对象中的函数称为方法
Object.keys() 返回数组,拿到对象所有的键
Object.values() 拿到所有值
Object.entries() 返回二维数组,拿到键值
for...in...遍历对象
for...of...默认不可遍历对象,因为它只能遍历可迭代对象

一个函数被new操作符调用后,它会执行如下操作:
1.在内存中创建一个新的对象(空对象)
2.这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性
3.构造函数内部的this,会指向创建出来的新对象
4.执行函数的内部代码(函数体代码)
5.如果构造函数没有返回非空对象,则返回创建出来的新对象。

构造函数的名称使用大驼峰,普通函数使用小驼峰

浏览器中存在一个全局对象:window
函数也是对象

JS常见内置类:
包装类:默认情况下,当我们调用一个原始类型的属性或者方法时,会进行如下操作
1.根据原始值,创建一个原始类型对应的包装类型对象
2.调用对应的属性或方法,返回一个新的值
3.创建的包装类对象被销毁
4.通常JS引擎会进行很多优化,可以跳过创建包装类的过程在内部直接完成属性的获取或者方法的调用
undefined和null没有包装类
数字类型:Number
toString、toFixed、parseInt、parseFloat等等方法
IEEE754 使运算一些小数导致丢失精度;Math.pow 幂运算,Math.sqrt开根号,Math.ceil向上取整,Math.floor向下取整
random公式:[a,b]区间内的随机数是parseInt(Math.random() * (b-a+1)) + a;
字符串类型:
字符串在定义后是不可被修改的,只能重新赋值
indexOf 查找子串、ES6新增includes是否包含子串、是否以xxx开头/结尾:startsWith、endsWith、替换字符串replace
slice、substr、substring截取子串,charAt得到指定位置字符,toUpperCase 转大写、toLowerCase 转小写、concat 字符串拼接
删除首尾空格 trim , 字符串切割 split 返回数组
数组类型:
push/pop 在数组尾部添加/删除元素,unshift/shift 在头部添加/删除元素。前者运行较快
arr.splice(start,deleteCount[,新增的元素]) 可以添加、删除、替换元素。修改数组本身。
arr.slice()截取子串,concat拼接数组,join 将数组转字符串, 数组内查找元素索引indexOf
高阶函数 arr.find(fn) 用于查找复杂元素,返回找到的元素。findIndex查找元素索引。
arr.sort(fn) 比较a,a-b,b结果小于0,a会放到前边,如果大于0,b被放到a的前边。从小到大排列。
arr.reverse() 返回新的倒叙数组,其他: forEach/filter/map/reduce

日期对象Date
UTC是标准时间
new Date() 获取当前时间
日期的表示方式有两种:RFC 2822 和 ISO 8601

DOM相当是JS和HTML、CSS之间的桥梁。通过浏览器提供的DOM API ,可以对元素以及其中的内容做任何事情。
节点的nodeType属性可以显示这个节点的具体类型:
1:元素节点;3:文字节点;8:注释节点;9:document节点;10:DTD节点
document.getElementById 兼容IE6
document.getElementsByTagName 兼容IE6
document.getElementsByClassName 兼容IE9
document.querySelector 兼容IE9,IE8部分兼容
document.querySelectorAll 兼容IE9,IE8部分兼容

在标准的W3C规范中,空白文本节点也应该算作节点,但在IE8及之前的浏览器中会有一定的兼容问题,他们不把空文本节点当作节点

从IE9开始支持一些“只考虑元素节点”的属性

| 关系 | 考虑所有节点 | 只考虑元素节点
| 子节点 | childNodes | children
| 父节点 | parentNode | parentNode
| 第一个子节点 | firstChild | firstElementChild
| 最后一个子节点 | lastChild | lastElementChild
| 前一个兄弟节点 | previousSibling | previousElementSibling
| 后一个兄弟节点 | nextSibling | nextElementSibling
<body>
    <div class="box">
      <input type="button" value="按钮1" class="btn" />
      <input type="button" value="按钮2" class="btn" />
      <input type="button" value="按钮3" class="btn" />
      <input type="button" value="按钮4" class="btn" />
      你好
      <p>hello</p>
    </div>
    <script>
      var box = document.querySelector(".box");
      // 封装一个函数,这个函数可以返回元素的所有子元素节点(兼容到IE6),类似children功能
      function getChildren(node) {
        // 结果数组
        var children = [];
        // 遍历所有子节点,判断每个子节点的nodeType是不是1
        for (let i = 0; i < node.childNodes.length; i++) {
          if (node.childNodes[i].nodeType === 1) {
            children.push(node.childNodes[i]);
          }
        }
        return children;
      }
      console.log(getChildren(box));
    </script>
  </body>

获取、设置元素节点的不符合W3C标准的属性时,需要使用setAttribute()getAttribute()
如果是data-*的属性,可通过dataset属性设置(HTML5新增)

创建节点:document.createElement 挂在到某个节点下 xxx.appendChild或insertBefore
删除节点:父节点.removeChild(要删除的子节点);克隆节点:老节点.cloneNode(true) 参数true表示深度克隆

常见的鼠标事件监听:
onclick 单击 、ondblclick 双击 、 onmousedown 鼠标被按下 、 onmouseup 鼠标按键被抬起 、onmousemove 鼠标移动
、 onmouseenter 鼠标进入(onmouseover 冒泡) 、 onmouseleave 鼠标离开( onmouseout 冒泡)
常见表单事件监听:
onchange、onfocus、onblur、onsubmit、onreset
事件的传播是先从外到内,再从内到外。(捕获和冒泡)onxxx(DOM0级事件监听)的方式只能监听冒泡阶段
DOM2级事件监听addEventListener 最后的参数true是可监听捕获阶段
注:最内部元素不再区分捕获和冒泡,会执行卸载前面的监听。
如果给一个元素设置多个同名事件,DOM0级写法后面写的会覆盖前面写的,DOM2级会按顺序依次执行
鼠标位置:
clientX 相当于浏览器的水平坐标
clientY 相当于浏览器的垂直坐标
pageX 相当于整张网页的水平坐标
pageY 相当于整张网页的垂直坐标
offsetX 相当于事件源元素的水平坐标(会计算最内部元素,所以内部不应再有子元素)
offsetY 相当于事件源元素的垂直坐标(会计算最内部元素,所以内部不应再有子元素)

阻止默认行为:e.preventDefault 阻止事件传播(冒泡/捕获):e.stopPropagation

e.charCode 属性用于onkeypress事件中,表示用户输入的字符码
e.keyCode 属性用于onkeydown和onkeyup,表示用户按下的键码
鼠标滚轮事件是onmousewheel,deltaY属性表示鼠标滚动方向,下滚时返回正值,上滚时返回负值。

事件委托:
要使用能够冒泡的事件,target是触发此事件最早的元素,currentTarget是事件处理程序附加到的元素

窗口尺寸相关属性:
innerHeight 浏览器窗口的内容区域的高度,包含水平滚动条
innerWidth 浏览器窗口的内容区域的宽度,包含垂直滚动条
outerHeight 浏览器窗口的外部高度
outerWidth 浏览器窗口的外部宽度

获得不包含滚动条的窗口宽度:document.documentElement.clientWidth

在窗口大小改变后会触发resize事件

window.scrollY 表示在垂直方向已滚动的像素值 (只读)
document.documentElement.scrollTop 属性也表示窗口卷动高度
所以为了更好的兼容性,可以同时写上方两个属性

在窗口被卷动后,会触发scroll事件,可以使用window.onscroll或者window.addEventListener('scroll')来监听

window.navigator内含有此次活动的浏览器相关属性(浏览器名称、版本、操作系统等)

window.location 标识当前所在网址,可以通过这个属性让浏览器跳转页面
window.location.reload(true) 方法重载当前页面,入参true表示从服务器强制加载
window.location.search 拿到当前浏览器get请求的查询参数

DOM元素都有offsetTop属性,表示此元素到定位祖先元素的垂直距离。(在祖先中离自己最近并有定位属性的元素)

reduce 计算 汇总 收敛 把一个数组中的一堆值计算出来一个值(最大值、平均值、和 等等)从左往右
例: 求数组中所有的和 let arr = [1,2,3]可以只传一个函数,也可以传第二个参数:初始值.如果没有传初始值,val就是第一个元素,item是第二个

// arr.reduce(function(当前值,当前元素,当前索引,老数组){},0)
arr.reduce( function( val, item, index, origin ) {
    return val + item; // 0+1 1+2 3+3 (返回值会成为下一次函数执行的val)
    }, 0 )
    // reduceRight从右往左算

Object.assign(obj1,obj2,obj3)合并方法,会把后面的对象合并到第一个对象并返回。结果会===第一个对象.

可以通过Array.from()转换成数组:
所有可遍历的数组:字符串、Set、Map、NodeList、arguments 、拥有length属性的任意对象,而且属性名是数值型或字符串型数字。 Array.from()第二个参数是一个回调函数相当于map方法,将即将形成的数组每一项做一下处理。第三个参数是要修改为的this指向。

前端

请先 登录 再评论