JS第四周

DAY1

一丶继承

1.父对象的成员(属性和方法),子对象可以直接使用

2.为什么继承:代码重用!节约内存空间

二丶JS的面向对象是基于原型(爸爸)的

1.什么是原型:保存一类子对象共有属性和共有【方法】的父对象(原型对象),每个对象天生就有一个原型

2.*获取原型对象:2种

(1)对象名.__proto__; - 前提:必须先创建出一个对象,才可以使用此属性找到原型对象

(2)构造函数名.prototype; - 构造函数名:Array、Function、Date、RegExp、h52204...     - 哪怕没有创建过任何对象也能找到原型

3.*****两链一包

(1)作用域链:以函数EC的scope chain属性为起点,经过AO逐级引用,形成的一条链式结构,作用:查找变量的,带来了变量的使用规则:优先使用自己的,自己没有找全局,全局没有则报错

(2)闭包:保护了一个可以反复使用的局部变量的词法结构

(3)原型链:每个对象都有一个.__proto__的属性,可以不断的连续.找到爸爸-爷爷-祖祖...形成的一条链式结构

A.经过尝试,发现最顶层:Object.prototype是对象的原型,所有也就有了一句话:万物皆对象

B.作用:查找属性和方法,自己没有的属性和方法,可以自动顺着原型链进行查找,所以我们知道为什么人人都可以使用toString

4.获取到原型对象则可以设置共有属性和共有方法

(1)自有和共有

自有:保存在对象本地的属性

共有:保存在父(原型)对象的属性,所有的子对象都可以使用

5.笔试题***

(1)*如何判断自有和共有

a.判断自有:

obj.hasOwnProperty("属性名");
返回一个布尔值:true说明是自有,false可能是共有也可能是没有

b.判断共有:2个条件

不是自有:obj.hasOwnProperty("属性名")==false;

自动在原型链检查:"属性名" in 对象名; 
                    if(obj.hasOwnProperty("属性名")==false&&"属性名" in 对象名){
                        //共有
                    }

c.完整版公式

if(obj.hasOwnProperty("属性名")){
                        console.log("自有");
                    }else{
                        if("属性名" in 对象名){
                            console.log("共有")
                        }else{
                            console.log("没有")
                        }
                    }

 if (user.hasOwnProperty("geting")) {//这里要加引号!!!!
            console.log("自有");
        } else {
            if ("geting" in user) {
                console.log("共有")// 父亲有 自己没有
            } else {
                console.log("没有")//说明自己和父亲都没有这个属性 
            }
        }

(2)*修改或删除属性

修改和删除自有属性 

         修改:obj.属性名=新值;  // 

         删除:delete obj.属性名;

修改和删除共有属性   

        修改:原型对象.属性名=新值;   obj.__proto__."属性"=新值  //

        删除:delete 原型对象.属性名;  

(3)***为老IE的数组添加indexOf方法 - 这道题不是固定的:为某一类人设置一个方法

if(Array.prototype.indexOf===undefined){//我不希望主流浏览器也执行到这些代码,我只希望老IE执行到
                Array.prototype.indexOf=function(key,starti){//indexOf的执行原理
                    starti===undefined&&(starti=0);//说明用户没有传入开始位置,我们就给用户设置为从下标0开始查找
                    for(var i=starti;i<this.length;i++){//从开始位置处,循环数组后面的每一个文字和用户输入的关键字进行匹配
                        if(this[i]==key){
                            return i;//匹配到了返回对应的下标
                        }
                    }
                    //没匹配到,返回-1
                    return -1;
                }
            }

(4)***判断x是不是数组?4种方法

A 判断x是不是继承自Array.prototype
                    Array.prototype.isPrototypeOf(x);
                    如果返回true,说明是数组,否则不是数组

B 判断x是否是由构造函数Array创建的
                    x instanceof Array

C ES5提供了一个API:Array.isArray(x);

D***输出对象的字符串形式:
                    在Object的prototype原型上放着最原始的toString
                    原始的toString,默认输出[object 构造函数名]


        var arr = [1, 2, 3, 4];
        var obj = { "name": "呆老师", "age": 18 };
        var reg = /^\s$/;
        var now = new Date();
        //方法一     多态     我希望借用到函数:跳过爸爸,直接去找爷爷拿toString
        console.log(Object.prototype.toString.apply(obj) === "[object Array]");
        console.log(Object.prototype.toString.apply(arr) === "[object Array]");

        //方法二 、判断x是不是继承自Array.prototype  Array.prototype.isPrototypeOf(x);
        console.log(Array.prototype.isPrototypeOf(obj));
        console.log(Array.prototype.isPrototypeOf(arr));

        //方法三 ES5提供了一个API:Array.isArray(x); - 此方法不是人人都有,而且ES5以上的东西
        console.log(Array.isArray(obj))
        console.log(Array.isArray(arr)
        )

        //方法四 判断x是否是由构造函数Array创建的     x instanceof Array
        console.log(obj instanceof Array);//new Object === {}
        console.log(reg instanceof Array);//new RegExp === //
        console.log(now instanceof Array);//new Date
        console.log(arr instanceof Array);//new Array


(5)*实现自定义继承

实现两个对象之间的继承 : 子对象.__proto__=父对象;

直接匹配设置继承 : 构造函数名.prototype=父对象,时机:先设置好父对象,再创建子对象


DAY2

一丶ES5

1.保护对象:保护对象的属性和方法

(1)四大特性:每个属性都有四大特性

{
                    "value": 3500, //实际保存属性值的地方
                    "writable": true,//开关:控制着是否可以被修改
                    "enumerable": true,//开关:控制着是否可以被for in循环遍历到
                    "configurable": true//开关:控制着是否可以被删除
            }

修改四大特性:
                Object.defineProperties(obj,{
                    "属性名":{四大特性}
                })

例子

var user = {
            "id": 6666,
            "name": "健康",
            "will": "顺利"
        }
        Object.defineProperties(user, {
            "id": {
                writable: false, configurable: false //不可被修改 不可以被删除
            },
            "name": {
                configurable: false
            },
            "will": {
                enumerable: false //不可以被遍历
                , configurable: false, writable: false
            }
        })

        user.id = 8888;
        delete user.will;
        console.log(user);
        for (var i in user) {
        console.log(user[i]) //遍历不到will
        }

(2)三个级别

防扩展:禁止给对象添加任何新属性

                Object.preventExtensions(obj);

密封:禁止给对象添加任何新属性,也不能删除属性

                Object.seal(obj);

冻结:禁止给对象添加任何新属性,也不能删除属性,也不能修改属性

                Object.freeze(obj);

var user = {
            "id": 6666,
            "name": "健康",
            "will": "顺利"
        }

        Object.preventExtensions(user);//防扩展  禁止给对象添加任何新属性 但是可以删除
        user.get = "平安";
        delete user.id;
        console.log(user);

2.*****数组的新的API:3组6个

(1)判断:判断数组中的元素是否符合要求

A.every - 每一个:判断数组中的每个元素【都】要符合要求最后结果才为true,类似于&&,只要有一个不满足,结果则为false

语法:var bool=arr.every(function(val,i,arr){
//                console.log(val);//当前元素
//                console.log(i);//当前元素的下标
//                console.log(arr);//数组本身
                return 判断条件;
                       })

//判断数组是否【都】是偶数组成的
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [2, 4, 6, 8, 10];

     var bool = arr1.every(function (val, i, arr) {
            return val % 2 == 0;
        })
        var bool2 = arr2.every(function (val, i, arr) {
            return val % 2 == 0;
        })
        console.log(bool, bool2);

B.some - 有一些:判断数组中的是否【包含】符合要求的元素,只要有一个最后结果则为true,类似||,只要有一个满足,则为true,只有全都不满足,结果才为false

        语法:var bool=arr.some(function(val,i,arr){
                return 判断条件;
                       })

(2)*遍历:对每个元素执行相同 或 相似的操作

A.forEach:直接修改原数组

        语法:arr.forEach(function(val,i,arr){
                操作;
                       })

B.map:不修改原数组,返回新数组

        语法:var newArr=arr.map(function(val,i,arr){
                return 操作;
                       })

 var arr = [1, 2, 3, 4, 5];
        arr.forEach(function (val, i, arr) { //直接修改原数组
            arr[i] *= 10
        })

        var newArr = arr.map(function (val, i, arr) {
            return arr[i] * 2
        }) // 需要拿新数组接住

        console.log(arr);
        console.log(newArr);

(3)过滤和汇总

过滤filter:筛选出原数组之中符合条件的元素组成一个新数组!原数组不变!

        语法:var newArr=arr.filter(function(val,i,arr){
                return 判断条件;
                       })

汇总reduce:讲数组中每一个元素,取出来整合为一个最终结果

        语法:var sum=arr.reduce(function(prev,val,i,arr){
                return prev+val;
                       },基础值)

 var arr = [1, 2, 3, 4, 5];

        var newArr = arr.filter(function (val) {
            return val % 2 == 1; //选出奇数
        })
        console.log(arr);
        console.log(newArr);

        var sum = arr.reduce(function (prev, val, i, arr) { //prev 为0 相对于求累和的sum=0
            return prev + val;
        }, 100) //逗号后面可以放基础值 
        console.log(sum);

3.Object.create()方法:直接用父对象创建子对象,并且子对象扩展自有属性

语法:var 子对象=Object.create(父对象,{
            "自有属性名":{四大特性},
            ...
               })

4.严格模式

如何开启:"use strict",可以放在任何一个作用域的顶部 

禁止给未声明的变量赋值 - 解决了全局污染  将静默失败升级为了错误

5.*****call、apply、bind:不是自己的方法,也可以用到

(1)call、apply:【临时替换函数中的this】,借用

语法:

         要借用的函数.call(借用的对象,实参1,...);

         要借用的函数.apply(借用的对象,arr); - apply除了有借用的功能,还会悄悄的打散我们的数组

差别:

call,要求传入函数的实参必须单独参入

aplly,要求传入函数的实参必须是一个数组

(2)bind:【永久替换函数中的this】,买

语法:

        var 新函数=老函数.bind(指定的对象)

3件事:

        创建了一个和原函数功能完全一样的新函数

        将新函数中的this永久绑定为你指定的对象

        将新函数中的部分参数永久固定

强调:bind绑定在新函数中的this,无法被call、apply再次替换借走

(3)总结

如果临时调用一个函数,立刻执行时 -- call/apply

如果创建一个函数提前绑定this,不一定希望立刻执行 - bind

(4)使用场景

比较出数组中的最大值和最小值:Math.max/min.apply(Math,arr)

得到Object最原始的toString:Object.prototype.toString.call/apply(arr);

将类数组对象转为普通数组:var 新数组=Array.prototype.slice.call/apply(类数组对象)

ES5还提供了一个数组API,可以直接将类数组对象转为普通数组:var 新数组=Array.from(类数组对象)

二丶ES6:新语法

1.*模板字符串:简化字符串拼接,支持在模板字符串之中书写变量

语法:`我的名字叫${name}`

            console.log(`单价为:${price},数量为:${count},总价为:${price*count}`);//变量用${ } 包起来

在字符串中实现了一个简单的js环境

           console.log(`${hello.split('').reverse().join('')}`)//包起来才能实现JS环境

2.*let关键字:创建变量以后优先使用let,再考虑var

优点:

        解决了声明提前

        添加了块级作用域,一个{}就是一个块

        如果绑定事件时,用到了let来遍历,那么let会记录住你当前元素的下标 - 你以后再也不需要自定义下标了

3.*箭头函数:简化一切的回调函数

        去掉function,()和{}之间添加=>,形参只有一个可以省略()

        函数体只有一句话,省略{}

        函数体只有一句话,并且是return,省略{}和return


        arr1.some(function (val, i, arr) { return val % 2 == 0; })  //

        arr1.some(var=>val%2==0)

4.其他

*解构赋值
Set和Map类型
*模块化开发
*Promise
*Class 


DAY3

一丶DOM

1.什么是DOM:Document Object Model(文档对象模型)

(1)将每一个标签/属性/文本/注释/元素,都看作是一个DOM元素/节点/对象(提供了一些操作元素的属性/方法)

(2)面试题
 HTML/XHTML/DHTML/XML 分别是什么?

        HTML - 网页        

        XHTML - 更严格的HTML,HTML5->XHTML->HTML4.01

        DHTML - 动态的网页:D:Dynamic - 其实并不是新技术、新概念,是将现有技术的整合统称,让我们在离线时,网页也具有动态效果        DHTML:html+css+js(dom)

        XML - 未知的标记语言,一切的标记由自己定义,数据格式

(3)DOM原本是可以操作一切结构化文档的 HTML 和 XML,后来为了方便各类开发者分为了3部分

        *核心DOM:【无敌】,既可以操作HTML  又 可以操作XML    缺陷:API比较繁琐

        *HTML DOM:只能操作HTML,API简单,缺陷:比如属性部分,只能访问标准属性,不能访问自定义属性    

        XML DOM:只能操作XML,XML已经淘汰了 - 现在最流行的数据格式是JSON

        开发建议:优先HTML DOM,HTML DOM实现不了我们在用核心DOM进行补充

2.每个DOM元素都有三大属性

(1)elem.nodeType:描述节点的类型

(2)attrNode.nodeValue:描述节点的值

(3)***elem.nodeName:描述节点的名字        

        拿到当前元素的标签名,判断xx是什么标签

        注意:返回是一个全大写组成的标签名

        if(div.children[i].nodeName=="UL")  {  div.children[i].style.background="pink";}

3.*****递归:简单来说就是函数中,又一次调用了函数自己,迟早有一天会停下来

(1)何时使用:遍历DOM树,专门用于【遍历层级不明确】的情况,既可以遍历层级不明确的DOM树,也可以遍历层级不明确的数据!

(2) 如何使用:2步       

function 函数名(root){
            1、第一层要做什么直接做!

            2、判断他有没有下一级,如果有下一级,再次调用此函数,但是传入的实参是他的下一级元素
        }
        函数名(实际的根)

 function getChild(root) {
            root.style.border = "1px solid #000";
            for (var i = 0; i < root.children.length; i++) {
                getChild(root.children[i])
            }
        }
        getChild(ul);

(3)算法:深度优先!优先遍历当前系欸但的子节点,子节点遍历完才会跳到兄弟节点

(4)递归的缺点:同时开启大量的函数调用,大量消耗内存,只有一个情况才用:【遍历层级不明确】

4.递归 vs 循环

递归

        优点:直观、易用

        缺点:性能较低,尽量只在层级不明确的时候使用

循环

        优点:几乎不占用内存

        缺点:难

5.专门提供了一个遍历层级不明确的DOM树的API:TreeWalker - 这是一个在DOM树上行走的人

2步

先创建出tw:var tw=document.createTreeWalker

                        (根元素,NodeFilter.SHOW_ALL/SHOW_ELEMENT);

tw对象过后,你会得到一个方法,反复调用nextNode方法找到下一个节点,迟早有一天会等于null,说明没找到,公式

        while((node=tw.nextNode())!=null){
            node要干什么
        }

缺陷

        自动的跳过根元素,根元素是不会做任何操作的

        仅仅只能遍历层级不明确的DOM树,不能遍历层级不明确的数据

6.API直接找元素

(1)根据HTML的特点去找元素

ID:var elem=document.getElementById("id值");

*标签名和*class和name:var elems=document.getElementsByTagName/ClassName/Name("标签名/class名");

(2)***根据CSS选择器去找元素

单个元素

        var elem=document.querySelector("任意的css选择器");

        强调:万一选择器匹配到多个,只会返回第一个 没找到null

***多个元素

        var elem=document.querySelectorAll("任意的css选择器");

        强调:找到了返回集合,没找到返回空集合


DAY4

一丶操作元素

<标签 属性名="属性值" style="样式">内容</标签>    强调:页面上获取/设置到的一切数据都是字符串类型

1.元素的属性

*获取属性值

        核心DOM:elem.getAttribute("属性名");

        HTML DOM:elem.属性名="属性值";

*设置属性值:

        核心DOM:elem.setAttribute("属性名","属性值");

        HTML DOM:elem.属性名="属性值";

删除属性值:

        *核心DOM:elem.removeAttribute("属性名");

        HTML DOM:elem.属性名="" - 删除不推荐使用HTML DOM,删除不干净属性节点,而有的属性,光有属性名就已经具有功能了

2.元素的样式

*内联样式:优先级最高,一定会覆盖其他的样式

3.创建元素并且渲染DOM树:3步

创建空标签

        var elem=document.createElement("标签名");

添加必要的属性和事件

        elem.属性名="属性值";

        elem.on事件名=function(){操作}

上树:将js内存中的新标签放到DOM树上

        *父元素.appendChild(elem); - 将elem追加到父元素里当最后一个儿子

        父元素.insertBefore(elem,已有子元素) - 将elem追加到父元素里,但是会插入在已有子元素的前面,缺点:会影响到其他元素的下标

        父元素.replaceChild(elem,已有子元素) - 将elem追加到父元素里,但是会替换在已有子元素的

4.删除元素:elem.remove();

5.HTML DOM常用对象:简化【核心DOM】

(1)image对象:仅仅只是简化了创建语句

创建:var img=new Image()  ===  var elem=document.createElement("img");

(2)form对象:简化了查找元素

*专属事件:form.οnsubmit=function(){//提交事件:只会再提交的一瞬间执行
                return false;//阻止提交
               }

(3)*select对象

属性

        1、select.options;//得到select下面所有的option,完全等效于xx.children;

        2、*select.selectedIndex;//得到当前选中项的下标,当时做二级(多级)联动就用到了他

方法

        1、*select.add(option);//完全等效于appendChild

         2、select.remove(i);//删除下标为i的option

专属事件

        select.οnchange=function(){//只有选中项发生变化了才会触发}

6.*option对象:仅仅只是简化了创建语句,但是非常牛逼

创建:var opt=new Option("innerHTML","value");

一句话完成四个操作

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

        直接让option上树到select里

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值