js基础学习4

253 阅读8分钟

ES5

1.保护对象

对象的每一个属性都有4大特性

  • true 保存实际值
  • writable 开关:控制属性是否可以被修改 默认true
  • enumerable 开关:控制属性是否可以被for in循环 默认true
  • configurable 开关:控制属性是否可以被删除 默认true
    • 一旦被设置为false,则不允许修改其他特性,改为false则不可逆

修改对象的某个属性

Object.defineProperty(xx,"id",{特性})

Object.defineProperties(xx,{
    "id":{四大特性},
    "name":{四大特性},
    "salary":{四大特性}
});

保护对象的三个级别

  • 防扩展/防添加 Object.preventExtensions(obj)
  • 密封(防添加、防删除) Object.seal(obj)
  • 冻结(防添加、防删除、防修改) Object.freeze(obj)

2.数组的新API(简化for循环)

判断

every 每一个都满足(类似&&) 任一为false,则为false

some 任一满足(类似||) 任一为true,则为true

    arr.every/some(function(val,i,arr){
        return 判断条件
    })

注意:

  • 三个参数val i arr 并非都需要传入,看需要使用哪些
    • val 当前值
    • i 当前值下标
    • arr 数组本身
  • function中的return未写时,默认为undefined

遍历

forEach 直接修改原数组

arr.forEach(function(val,i,arr){
    arr[i]*=2;//arr[i]=val*2
})

map 不修改原数组,直接返回新数组

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

汇总和过滤

过滤: 筛选出符和条件的元素(不修改原数组)

var subArr=arr.filter(function(val,i,arr){
    return 条件;
})

汇总

var subArr=arr.reduce(function(prev,val,i,arr){
    return prev*val;
},base)

3.根据一个父对象创建子对象

var 子对象=Object.create(父对象){
    "属性1":{四大特性},
    "属性2":{四大特性},
    "属性3":{四大特性}
}

4.call/apply/bind:替换了函数中的this

call/apply

临时替换了函数中的this,类似“借”。两者的区别为传参形式

call 实参单独传入方法名.call(借用对象,实参)

apply 传入实参整理为数组,传入数组参数方法名.apply(借用对象,[实参])

常用:

  1. Object.prototype.toString.call/apply(数组);
  2. Math.max/min.apply(Math,arr);
  3. 将类数组转为普通数组lis=Array.prototype.slice.call(this)
//摇号
var lis=document.getElementsByTagName("li");
var list=document.getElementsByTagName("ul")[0];

lis=Array.prototype.slice.call(lis);

var nums=[];

while(nums.length<lis.length){
    var r=parseInt(Math.random()*(lis.length)+1);
    if(nums.indexOf(r)==-1){
        nums.push(r)
    }
}

lis.forEach((val,i) => val.setAttribute("count",nums[i]));
lis.sort((a,b) => a.getAttribute("count")-b.getAttribute("count"));
lis.forEach(val => list.appendChild(val));

bind

永久替换了函数中的this,类似“买”【不会立即执行】

var 新函数名=方法名.bind(永久绑定的对象,永久绑定的参数,...);

  • 创建了一个功能和原函数完全相同的新函数
  • 将新函数的this永久绑定为指定对象
  • 将新函数中部分固定参数提前永久绑定

5.严格模式

开启严格模式use strict

  • 放在作用域顶部
  • 严格模式下禁止给未声明变量赋值
  • 将静默失败升级为错误

ES6

1.模板字符串

支持直接在字符串中书写变量我的名字叫${name}

2.块级作用域

将var替换为let,用于创建变量

  • let前不允许出现未声明的同名变量(解决声明提前)
  • 添加了块级作用域,{}相当于一个块
  • 绑定事件时记录当前元素下标,不需要自定义下标 for(let i=0;i<lis.length;i++){}

3.箭头函数:简化回调函数

去掉function,()和{}之间添加=>

  • 若形参只有一个,省略()
  • 若函数体只有一句话,省略{}
  • 若函数体只有一句return,return可以省略
  • 箭头函数中的this会指向外部的对象

4.for of循环

for(var v of arr){console.log(v)}

  • v:value,
  • 循环拿到每个值
  • 不能遍历hash,不能遍历对象
  • 不能直接修改原数组,返回新数组

DOM

Document Object Model 提供了专门操作HTML文档的API

1.概念

DHTML:动态的HTML,一切实现网页动态效果的技术的统称。DHTML=HTML+CSS+JS(DOM)

HTML/XHTML/DHTML/XML
HTML:超文本标记语言,网页
XHTML:可扩展超文本标记语言,更严格的网页
DHTML:动态网页
XML:数据格式

DOM:本来可以操作一切结构化文档(XHTML/XML),分为三部分:

  • 核心DOM:万能,但API繁琐
  • HTML DOM:只能操作HTML文档,API简单
  • XML DOM

2.DOM树

保存所有网页内容的树状结构,树根(document)不需要创建,由浏览器的js解释器自动创建

DOM节点/对象/元素:一个标签、文本、属性、注释等

每个阶段都有三大属性:

  1. xx.nodeType 获取xx的节点类型

document(9)、文本节点(3)、属性节点(2)、元素标签(1)

  1. xx.nodeValue 获取属性节点的节点值
  2. xx.nodeName 获取属性节点的名字
  • 应用:直接找自带可能找到多个标签,但想对不同标签做对应操作
  • 注意:获取到的标签名都是大写

3.通过节点关系获取元素

  • 子元素找父元素: xx.parentNode(单个元素)
  • 父元素找子元素: xx.children(集合)
  • 父元素找第一个子元素: xx.firstElementChild(单个元素)
  • 父元素找最后一个子元素: xx.lastElementChild(单个元素)
  • 前一个兄弟元素 xx.previousElementSibling(单个元素)
  • 后一个兄弟元素 xx.nextElementSibling(单个元素)

4.递归

函数中,再次调用自己,但会让它停下来

  • 作用:专门用于遍历层级不明确的树状结构
  • 步骤:
    1. 创建函数,传入实参树根,形参接住,直接做第一层的操作 function f1(root){第一层操作}

    2. 调用函数 f1(实际的根元素)

//例:给表格添加边框
function getChildren(root){
    root.style.border="solid 1px #000";
    for(var i=0;i<root.children.length;i++){
        getChildren(root.children[i]);
    }
}
  • 算法:深度优先,优先遍历当前节点的子节点,子节点遍历完才会跳到兄弟节点
  • 递归优点:直观易用
  • 递归缺点:效率低,占内存空间。用于遍历层级不明确的DOM

5.遍历API

用于遍历层级不明确的树状结构,步骤:

  1. 创建treewalker对象 var tw=document.createTreeWalker(root,NodeFilter.SHOW_ALL)

var tw=document.createTreeWalker(root,NodeFilter.SHOW_ELEMENT)找元素

  1. 反复调用nextNode方法 while((var node=tw.nextNode())!=null){node;//当前节点做什么操作}

注意:深度优先算法,此方法必须跳过起点

6.纯循环遍历层次不明确的树状结构

不用遍历API(只能遍历页面元素);也不用纯循环遍历(难度大);遇到层级不明确时,使用递归(不仅遍历元素,还遍历数据)

7.查找元素

按HTML特点查找

  • idvar elem=document.getElementById("id");
  • 标签var elems=document.getElementsByTagName("标签名");
  • classvar elems=document.getElementsByClassName("class");
  • namevar elems=document.getElementsByName("name");

按css选择器进行查找

  • 单个元素:未找到时null,多个元素只会找到第一个 var elem=document.querySelector("任意css选择器");
  • 多个元素:找到是一个集合,未找到时一个空集合 var elems=document.querySlectorAll("任意css选择器");

getxx和querySelectorxx的区别:

  1. 返回结果不同
    • get:返回的时一个动态集合(DOM树每次被修改,都会再次查找)
    • querySelector:返回的是一个静态集合(DOM树每次被修改,不会再次查找,只管第一次找到的结果)
  2. 动态集合:不支持forEach;静态集合:支持forEach(类数组)
  3. 复杂查找时,使用querySelectorAll

8.操作元素

一切的获取都是为了判断,一切的设置都是为了修改

内容

  1. innerHTML 支持标签,且无兼容性问题
  • 获取:elem.innerHTML
  • 设置:elem.innerHTML="新值"
  1. innerText 不支持标签,有兼容性问题
  • 获取:elem.innerText
  • 设置:elem.innerText="新值"
  1. value 专为input、select准备(select可获取option选项)

属性

  1. 获取属性
  • 核心DOM:elem.getAttribute("属性名");
  • HTML DOM:elem.属性名 注意:核心DOM是万能用法,可以操作一切属性;HTML DOM只能操作标准属性
  1. 设置属性值
  • 核心DOM:elem.getAttribute("属性名","属性值");
  • HTML DOM:elem.属性名="属性值";
  1. 删除属性值:会删除整个属性节点
  • 核心DOM:elem.removeAttribute("属性名"); 注意:elem.属性名="";赋值为空,但未删除。有的属性仅有属性名也具有效果(disable、href)
  1. 判断属性值:只能判断有无属性
  • 核心DOM:elem.hasAttribute"属性名" =>if(elem.getAttribute("属性名")==值){}

样式

  1. 内联样式表:优先级最高,指挥操作某个样式,不会牵一发而动全身
  • 获取:elem.style.css属性名
  • 设置:elem.style.css属性名="css属性值";
  1. 内部/外部样式表:document.styleSheet[i].cssRules[i].style.background
  • 获取样式表 var sheet=document.styleSheet[i];
  • 获取样式规则 var rules=sheet.cssRules;
  • 获取想要的操作 var rule=rules[i];
  • 获取或修改样式 rule.style.background="pink";

9.创建元素&渲染页面&删除元素

创建元素

  1. var 空标签=document.createElement("标签名");
  2. 设置必要属性和方法
  • 空标签.属性名="属性值";
  • 空标签.on方法=function(){}
  1. 渲染页面
  • 添加:父元素.appendChild(新元素);新元素会插入到父元素最后
  • 插入:父元素.insertBefore(新元素,已有子元素);新元素会插入到已有子元素之前
  • 替换:父元素.replaceChild(新元素,已有子元素);新元素会替换已有子元素
  1. 删除元素 元素.remove

10.HTML DOM 提供的对象

简化部分核心DOM操作

image

简化创建var img=new Image();

  • 在DOM中,不是人人都有构造函数创建方式

form

  • 简化查找元素 var form=document.forms[i];
  • 简化查找表单控件 var input=form.elements[i]
  • 专属事件 onsubmit提交时触发,可阻止提交return false

select

  • 专属事件 onchange选中项发生改变时触发
  • 属性
    • options===children 获取到select下所有option
    • selectedIndex 获取到当前选中项下标
  • 方法
    • select.add(option) 获取到select下所有option
    • select.remove(i) 删除select中第i个option

option

  • 简化创建 var opt=new Option("innerHTML","value");

select.add(new Option("innerHTML","value"))

BOM

Browser Object Model 浏览器对象模型:提供了专门用于操作浏览器的API(没有标准,且使用较少。大部分浏览器厂商已统一实现,除老IE)

BOM对象:window、history、location、navigator、event、screen...

1.window对象

  • 浏览器中,window代替了ES的Global,充当全局作用域(包含了所有全局对象、变量、函数)
  • 指代了当前浏览器的窗口

网页打开新链接的方式

  1. 替换当前页面,可以后退
  • HTML <a href="#">链接</a>//默认target="_self"
  • js:先添加点击事件 open("url","_self")
  1. 新窗口打开,可以打开多个
  • HTML <a href="#" target="_blank">链接</a>
  • js:先添加点击事件 open("url","_blank")
  1. 新窗口打开,只能打开一个【应用:支付结账窗口】
  • HTML <a href="#" target="自定义">链接</a>
  • js:先添加点击事件 open("url","自定义")
  1. 替换当前页面,禁止后退【应用:结账完毕后,不允许后退】
  • js: location.replace(新url)//替换当前网址,不会产生历史记录
    • history对象 保存了当前窗口的历史记录,功能:前进后退
    • location 保存了当前窗口正在打开的url

window对象

  1. 属性:
  • 获取浏览器窗口的大小
    • 屏幕的大小 screen.width/height
    • 完整浏览器的大小 outerWidth/outerHeight
    • 文档显示区域的大小 innerWidth/innerHeight
  1. 方法:
  • 打开新窗口 open("url","自定义name","width=,height=,left=,top=");
    • height、width 没有单位,宽高设置不小于200
    • 若未传入参数3,新窗口会和浏览器并为一体
    • 若传入参数3,新窗口会脱离浏览器,可能会被浏览器拦截
  • 关闭窗口 窗口.close();
  • 修改窗口大小(只能用于新窗口) 新窗口.resizeTo(宽,高);
  • 修改窗口位置 新窗口.moveTo(x,y)
//鼠标跟随事件
<script>
    window.onmousemove=function(e){
        var x=e.pageX;
        var y=e.pageY;
        var img=new Image();
        img.src="2.png";
        img.style.top=y+"px";
        img.style.left=x+"px";
        img.onload=function(){//加载事件:图片加载完毕后在执行的代码
            img.style.transform="rotateY(360deg)";//图片的加载速度比JS的执行速度慢	
            img.style.opacity="0";//图片的加载速度比JS的执行速度慢	
        }
        bd.appendChild(img);
    }

    setInterval(()=>{
        var imgs=document.querySelectorAll("img");
        for(var i=0;i<imgs.length-50;i++){
            imgs[i].remove();
        }
    },1000)
</script>
  • 定时器
    • 周期性定时器(先等待,再执行一次)重复
      • 开启 timer=setInterval(function(){},毫秒数)
      • 停止 clearInterval(timer)
    • 一次性定时器(先等待,再执行一次)
      • 开启 timer=setTimeout(function(){},毫秒数)
      • 停止 clearTimeout(timer)
//底层相同,可以互换

//周期性->一次性
timer=setInterval(()=>{
    console.log(1);
    clearInterval(timer);
},1000);

//一次性->周期性
function f1(){
    timer=setTimeout(()=>{
        console.log(1);
        f1()
    },1000);
}
f1()

窗口底层都有一个名字,若出现重复的名字则新窗口会替换掉原来的窗口

扩展

  1. 去掉开头结尾的空白字符 str.trim
  2. 弹出用户确认框 confirm
  • 结果为bool(确认->true,取消->false)
  1. a标签功能:跳转、锚点、下载、打开图片、直接书写js
  • 下载:支持exe安装包、rar、zip
  • 书写js: <a href="jsvascript:js代码;"></a>
  1. 获取鼠标位置
onmouseover=function(e){
    e.screebX/Y;//获取屏幕上的坐标
    e.clientX/Y;//获取相对于浏览器坐标
    e.pageX/Y;//获取相对于页面坐标
}