JS高频面试题,请查阅,务必收藏持续更新

this的指向?

this:是函数体内的内置对象,作用域在函数体内

1.与事件体连用,代表触发该事件的元素

2.与普通方法连用,代表调用该方法的对象

3.与构造方法连用,代表new出来的实力化对象

4.出现在箭头函数内的this,是父元素的前缀

闭包

闭包的概念:函数嵌套另一个函数,被嵌套的函数称为闭包函数

闭包的作用:可以让主函数在函数体外使用其内部的变量

闭包的实现:

1.在主函数f1内部定义子函数f2,在子函数f2中操作f1的局部变量

2.将子函数f2作为主函数的返回值返回

3.通过外界的全局变量f绑定f1的返回值f2函数

4.这样就延长了f2和count的生命周期

5.就可以通过f使用f1内部的变量count;

闭包的缺陷:大量使用闭包就有可能造成内存泄漏,因为闭包打破了垃圾回收机制

* 扩展:解决了面向对象共有私有的属性问题

  function f1() {
  var count = 0;
  var f2 = function() {
             return ++count;
         }
 ​
         return f2;
     }
 ​
     var f = f1(); //f == f2
     console.log(f());
     console.log(f());
     console.log(f());

接口

### 接口

接口通常只被访问的服务器文件。

发送请求访问接口文件,获取响应内容。

### 访问接口的四要素

1.url

2.访问方式 get post

3.请求参数

4.返回响应的数据格式

promise的总结

promise的总结:

promise是一个处理异步操作的容器.

它的主要作用:

1.将回调地狱的写法改为平级调用

2.包裹异步操作(用来处理请求和响应)

3.promise的构造方法的参数时一个回调函数,

该回调函数又有两个参数,也是回调函数

4.通过then方法由外界传递回调函数给主函数

其实就是为了通过回调函数获取响应值

promiseAjax.html

   function ajaxFun(type, url, isAsyn, data) {
         //1.
         let xhr = new XMLHttpRequest();
 ​
         type = type.toLowerCase();
 ​
         //2.
         if (type == "get") {
             let urlParam = url;
             if (data != "") {
                 urlParam += "?" + data;
             }
             xhr.open(type, urlParam, isAsyn);
             xhr.send();
         } else if (type == "post") {
             xhr.open(type, url, isAsyn);
             xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
             xhr.send(data);
         } else {
             console.log("类型错误");
         }
 ​
         //4.
         // promise用来包裹异步操作
 ​
         let p = new Promise(function(success, failed) {
             xhr.onreadystatechange = function() {
                 if (xhr.status == 200 && xhr.readyState == 4) {
                     success(xhr.responseText);
                 } else if (xhr.readyState == 4) {
                     failed();
                 }
             }
         });
 ​
         return p;
     }
 ​
     //使用者视角
     ajaxFun("get", "2.ajaxFun.ph", true, "name=laowang&age=18").then(fun1, fun2);
 ​
     // ajaxFun("get", "6.ajaxFun.php", true, "name=laowang&age=18", fun);
 ​
     function fun1(resText) {
         console.log("最终就是为了得到:" + resText);
     }
 ​
     function fun2() {
         console.log("失败");
     }

promise的all和race

场景:页面在渲染的时候,有时需要向多个不同的服务器发请求,等所有服务器拿到数据后,

再一起渲染页面

all:Promise.all方法,可以使所有请求都接收响应后,统一返回所有响应内容

场景:需要的响应内容很多服务器都有,可以同时发送多个请求,哪个快用哪个响应。

race

jsonp

No 'Access-Control-Allow-Origin' 不允许跨域访问

跨域:一个网站的页面访问两另一个服务器的文件

同源策略:浏览器的安全机制,只能访问同IP,通端口,同协议的文件

跨域访问:

前端跨域

jsonp

jsonp跨域的原理

1.src是跨域的

2.script+src可以实现访问远程服务器的文件内容

3.前端和后端约定一个函数名,前端写函数定义

后端写函数调用

function fun(resText) {

console.log(resText);

}

fun("heihei");

后端跨域

CROS

jsonp.html

 // function fun(resText) {
     //     console.log(resText);
     // }
 ​
     // fun("heihei");
 ​
     // 后端跨域
     //     CROS
 ​
 ​
     let xhr = new XMLHttpRequest();
     xhr.open("get", "http://10.12.151.25/first.php", true);
     xhr.send();
     xhr.onreadystatechange = function() {
         if (xhr.readyState == 4 && xhr.status == 200) {
             fun(xhr.responseText);
         }
     }
 ​
     function fun(resText) {
         console.log(resText);
     }
 </script>
 <!-- <script src="4.jsonp.txt"></script>
 <script src="http://10.12.151.25/first.txt"></script>
 <script src="4.jsonp.php"></script>
 <script src="http://10.12.151.25/first.php"></script> -->
 <!-- <script src="4.jsonp.php?cb=fun&wd=2"></script> -->
 <!-- <script src="http://10.12.151.25/first.php?cb=fun&wd=1"></script> -->

jsonp.php

 <?php
     header("Content-type:text/html;charset=utf-8");
     // header("Access-Control-Allow-Origin:*");
     // echo "fun('凢凢')";
 ​
     $cb = $_GET["cb"];
     $wd = $_GET["wd"];
 ​
     if($wd == 1){
         echo "$cb('嘤嘤嘤')";
     }else if($wd == 2){
         echo "$cb('嘿嘿嘿')";
     }
 ?>

jsonp.txt

 fun("今天星期六"); 

AJAX请求步骤

//发请求接响应

发请求接响应

let xhr = new XMLHttpRequest();

xhr.open("get", "4.baiduquery.php?wd=" + this.value, true);

xhr.send();

xhr.onreadystatechange = function() {

if (xhr.readyState == 4 && xhr.status == 200) {

fun(xhr.responseText);

}

}

XMLHttpRequest的属性与状态码

  let xhr = new XMLHttpRequest();
     console.log(xhr.readyState);
     // xhr.open("传参的方式get|post","url服务器地址,是否异步);
     xhr.open("get", "1.server.txt", true);
     console.log(xhr.readyState);
     // xhr.send([post传参时的请求参数]);
     xhr.send();
 ​
     //readyState是xhr对象在发请求接相应不同时刻的状态码
     //0:代表创建了一个XMLHttpRequest对象
     //1:代表调用了open方法
     //只有234会触发onreadystatechange
     //2:调用send方法,把数据发送出去
     //3:数据发送到了服务器
     //4:服务器接收数据且完成解析
 ​
     xhr.onreadystatechange = function() {
         //为什么readyState要等于4?
         console.log(xhr.readyState);
         // status:http协议的状态,200为数据交互成功
         if (xhr.readyState == 4 && xhr.status == 200) {
             fun(xhr.responseText);
         }
     }
 ​
     function fun(resText) {
         console.log(resText);
     }

readyState状态码

readyState是xhr对象在发请求接相应不同时刻的状态码

0:代表创建了一个XMLHttpRequest对象

1:代表调用了open方法

只有234会触发onreadystatechange

2:调用send方法,把数据发送出去

3:数据发送到了服务器

4:服务器接收数据且完成解析

ajaxpost.html

 let oInput = document.querySelector("input");
 ​
     oInput.onblur = function() {
         let xhr = new XMLHttpRequest();
         //post传参注意事项:
         //1.url地址栏不能携带请求参数
         //2.open和send方法之间必须设置请求头
         //3.将请求参数写入send方法中
         xhr.open("POST", "2.ajaxPost.php", true);
         //以form表单post的方式传参
         xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
         // key1=value1&key2=value2
         xhr.send("userName=" + this.value);
         xhr.onreadystatechange = function() {
             if (xhr.status == 200 && xhr.readyState == 4) {
                 fun(xhr.responseText);
             }
         }
     }
 ​
     function fun(resText) {
         let oSpan = document.querySelector("span");
         // oSpan.innerHTML = resText;
         if (resText == "1") {
             oSpan.innerHTML = "注册失败";
         } else {
             oSpan.innerHTML = "注册成功";
         }
     }

ajax.php

 <?php
     header("Content-type:text/html;charset=utf-8");
 ​
     $userName = $_POST["userName"];
 ​
     $conn = mysql_connect("localhost","root","root");
 ​
     mysql_select_db('2207');
 ​
     $result = mysql_query("select * from student where stu_name = '$userName'",$conn);
 ​
     if(mysql_num_rows($result) == 1){
         echo "1";
     }else{
         echo "0";
         mysql_query("insert into student values (10,'$userName','M','1966-6-6')",$conn);
     }
 ​
     mysql_close($conn);
 ?>

returnJSON.html

   let xhr = new XMLHttpRequest();
    xhr.open("get", "3.returnJSON.php", true);
    xhr.send();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            fun(xhr.responseText);
        }
    };

    function fun(resText) {
        let json = JSON.parse(resText);
        console.log(json);
    }

returnJSON.php

<?php
    header("Content-type:text/html;charset=utf-8");

    //1.通过json的字符串返回
    // echo '{"name":"老王","age":18}';

    //2.通过json数组
    $arr = ["name"=>"刘能","age"=>18];
    //将键值对数组转为json字符串
    echo json_encode($arr);
?>

http协议get和post的区别?

get效率高,安全性差,携带数据量小 (五菱宏光)

post效率低,安全性高,携带数据量大 (武装押运)

ajaxGET和POST传参的区别?

1.get将请求携带在url,通过?分开,键值对方式传递

2.post不能再url中携带请求参数

3.需要在open和send间设置请求头

4.在send中以键值对的方式传递请求参数

封装ajax函数

function ajaxFun(type, url, isAsyn, data, callBack) {
    //1.
    let xhr = new XMLHttpRequest();

    type = type.toLowerCase();

    //2.
    if (type == "get") {
        let urlParam = url;
        if (data != "") {
            // 6.ajaxFun.php?name=laowang&age=18
            urlParam += "?" + data;
        }
        xhr.open(type, urlParam, isAsyn);
        xhr.send();
    } else if (type == "post") {
        xhr.open(type, url, isAsyn);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send(data);
    } else {
        console.log("类型错误");
    }

    //4.
    xhr.onreadystatechange = function() {
        if (xhr.status == 200 && xhr.readyState == 4) {
            //5.
            callBack(xhr.responseText);
        }
    }
}

功能:发请求,接收最终的响应内容

参数:

type:get/post

url:地址

isAsyn: true

data:key1=value1&&key2=value2

callBack:接收响应参数

cookie的删除

  //cookie没有直接删除的方法,只能间接删除
    //cookie的删除只针对于长生命周期

    // 删除的方法
    // a.将key对应的value设置为""
    // b.将expires=-1

    // let date = new Date();
    // date.setDate(date.getDate() + 10);
    // document.cookie = "name=laowang;expires=" + date;

    // document.cookie = "name='';expires=-1";

cookie的封装

 // document.cookie = "key=value";
    // document.cookie = "key=value;expires="+标准日期对象
    //增改
    function setCookie(key, value, day) {
        if (day == undefined) { //会话
            document.cookie = `${key}=${value}`;
        } else { //长生命周期
            let date = new Date();
            date.setDate(date.getDate() + day);
            document.cookie = `${key}=${value};expires=${date}`;
        }
    }

    setCookie("name", "蔡徐坤"); //会话级别
    setCookie("pwd", "123456", 10); //长生命周期

    //查
    function getCookie(key) {
        let strCookie = document.cookie; //"name=蔡徐坤; pwd=123456"
        let arrCookie = strCookie.split("; "); //["name=蔡徐坤"."pwd=123456"]

        for (let i = 0; i < arrCookie.length; i++) {
            let item = arrCookie[i].split("="); //["name","蔡徐坤"] ["pwd","123456"]
            if (item[0] === key) {
                return item[1];
            }
        }

        return "";
    }

    console.log(getCookie("name"));
    console.log(getCookie("pwd"));
    console.log(getCookie("heihei"));

    //删
    function delCookie(key) {
        setCookie(key, '', -1);
    }

    delCookie("pwd");

7 天免登录.html

<body>
    name:<input type="text"><br> pwd: <input type="text"><br>
    <select>
        <option value="0">无需免登陆</option>
        <option value="7">7天面免登陆</option>
        <option value="30">30天免登录</option>
    </select>
    <button>登录</button>
</body>

</html>
<script src="cookie.js"></script>
<script>
    if (getCookie("name") != "" && getCookie("pwd") != "") {
        location.href = "3.ok.html";
    } else {
        let oInputs = document.getElementsByTagName("input");
        let oSelect = document.querySelector("select");
        let oBtn = document.querySelector("button");

        oBtn.onclick = function() {
            switch (oSelect.value) {
                case "0":
                    break;
                case "7":
                case "30":
                    setCookie("name", oInputs[0].value, oSelect.value / 1);
                    setCookie("pwd", oInputs[1].value, oSelect.value / 1);
                    break;
            }

            location.href = "3.ok.html";
        }
    }
</script>

ajax的概念及作用

前提条件:只要发请求,就伴随着页面的刷新。

很多场景中,只需要页面的局部更新。

//--------------------------------

概念:

ajax (Asynchronous JavaScript And XML)

异步更新(局部更新)

AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分

网页的技术

这样可以和服务器进行少量交互,从实现页面的部分更新。

作用:

* 更自然、流畅的用户体验,对用户的操作即时响应

* 在不中断用户操作的情况下与Web服务器进行通信

* 更灵敏的响应用户访问,实现近似于桌面应用程序的交互效果

* 通过局部更新页面降低网络流量,提高网络的使用效率

同步异步

// 代码在执行时需要花费时间, 这样的时间分为两种
    // 1. 执行时间
    // 2. 等待时间

    // 同步代码:
    //     代码按照顺序一步一步执行, 前一步执行完, 后一步才能执行。

    // 1. 买菜
    // 2. 洗菜
    // 3. 切菜
    // 4. 烧水
    // 5. 炒菜

    // 异步代码:
    //     异步代码除了需要运行时间外, 还需消耗等待时间。 异步代码的执行方式, 当遇到需要消耗等待时间
    // 的代码时, 先跳过该代码, 执行后续代码。

    //-----------------------------------------------
    // 同步代码和异步代码的分类:
    // 凡是需要消耗等待时间的代码都称为异步代码
    // 1.定时器
    // setInterval(回调,1000);
    // 2.事件体
    // oBtn.onclick = function(){事件头
    //     事件体
    // }
    // 3.发请求接响应

    // a.只有同步代码遵循自上而下的执行顺序
    // b.同步代码优先执行

ajax的使用步骤

  //1.掏手机--->new XMLHttpRequest()创建一个ajax的核心对象
    let xhr = new XMLHttpRequest();
    //2.拨号--->调用open方法
    // xhr.open("发送请求的方式get/post", "请求的地址", true);
    xhr.open("get", "server.txt", true);
    //3.发射--->调用send方法
    xhr.send();
    //4.等待
    xhr.onreadystatechange = function() {
        // xhr.status == 200 打通电话了,嘟~嘟~嘟~
        // xhr.readyState == 4 接通电话 
        if (xhr.status == 200 && xhr.readyState == 4) {
            // 5.回馈你信息
            fun(xhr.responseText);
        }
    }

    function fun(resText) {
        console.log(resText);
    }

ajaxGet.html

    let oInput = document.querySelector("input");

    oInput.onblur = function() {
        let xhr = new XMLHttpRequest();
        //如何通过ajaxget的方式携带请求参数
        // url?key1=value1&key2=value2...
        xhr.open("get", "7.ajaxGet.php?userName=" + this.value, true);
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.status == 200 && xhr.readyState == 4) {
                fun(xhr.responseText);
            }
        }
    }

    function fun(resText) {
        let oSpan = document.querySelector("span");
        oSpan.innerHTML = resText;
    }

ajaxGet.php

<?php
    header("Content-type:text/html;charset=utf-8");

    $userName = $_GET["userName"];

    $conn = mysql_connect("localhost","root","root");

    mysql_select_db('2207');

    $result = mysql_query("select * from student where stu_name = '$userName'",$conn);

    if(mysql_num_rows($result) == 1){
        echo "尿了";
    }else{
        echo "注册成功";
        mysql_query("insert into student values (10,'$userName','M','1966-6-6')",$conn);
    }

    mysql_close($conn);
?>

phpConnMysql.php

<?php
    header("Content-type:text/html;charset=utf-8");

    //1.登录
    // mysql_connect('服务器的IP地址','用户名','密码'):返回值连接对象
    $conn = mysql_connect("localhost","root","root");

    if($conn){
        echo "连接成功"."<br>";

        //2.选择库
        mysql_select_db('2207');

        //3.数据库操作   mysql_query(sql语句,连接对象);
        //增  除了整型数据,其他数据字符串和日期都要用引号括起来
        // mysql_query("insert into student values (8,'凢凢','M','1999-5-16')",$conn);
        //删
        // mysql_query("delete from student where stu_name='凢凢'",$conn);
        //改
        // mysql_query("update student set stu_name = '易烊千玺' where stu_name = '蔡徐坤' ",$conn);

        //查
        //返回值为被查询到的结果集
        // $result = mysql_query("select * from student where stu_name ='刘能'",$conn);
        // mysql_num_rows(结果集):返回结果集的记录个数,常用于注册登录判断
        // echo mysql_num_rows($result);
        // if(mysql_num_rows($result) == 0){
        //     echo "注册成功";
        // }else{
        //     echo "注册失败";
        // }

        $result = mysql_query("select * from student",$conn);
        // mysql_fetch_assoc(结果集):返回当前游标所指向的记录,存储在对象中
        //                          每当函数运行完后,游标自动下移

        while($obj = mysql_fetch_assoc($result)){
            echo $obj["stu_id"]." ".$obj["stu_name"]." ".$obj["stu_gender"]." ".
            $obj["stu_date"]."<br>";
        }

        //4.关闭登录(退出)
        mysql_close($conn);
    }
?>

login.html

<body>
    <form action="2.login.php" method="get">
        <input type="text" name="userId"><br>
        <input type="text" name="userName"><br>
        <input type="submit" value="提交">
    </form>
</body>

login.php

<?php
    header("Content-type:text/html;charset=utf-8");

    $userId = $_GET["userId"];
    $userName = $_GET["userName"];
    
    // echo $userId." ".$userName;
    $conn = mysql_connect("localhost","root","root");

    mysql_select_db('2207');

    $result = mysql_query("select * from student where stu_id=$userId and stu_name='$userName'",$conn);

    if(mysql_num_rows($result) == 1){
        echo "用户已存在,请重新想名字";
    }else{
        echo "注册成功";
        mysql_query("insert into student values($userId,'$userName','M','1966-2-3')",$conn);
    }

    mysql_close($conn);
?>

http协议

基于请求和响应的数据传输协议

请求:B->S
url
    http://ip+端口号+文件路径

    http:// 照抄
    ip:在网络中计算机身份的唯一识别符(身份证号)
    端口号:某个计算机上的软件入口,通过端口号来区分电脑上的每个程序
    文件路径:文件的路径

    http://127.0.0.1/2207/Day_22/2.login.html
    http协议有get和post传参两种方式:

    get请求,将请求数据作为url一部分发送,不安全,传输数据量小,方便易用。
    post请求,传输数据量大,安全,一般做表单提交。

响应:S->B
200 OK        //客户端请求成功
404           //请求资源不存在,输入了错误的URL
500           //服务器问题

cookie的概念

cookie可以理解为是一个变量,它的作用其一,允许在页面间共享传递数据。

高级的解释方式:
会话->一个网页从打开到完全关闭的过程
cookie称为会话跟踪技术,在会话期间,可以在页面间共享传递数据

作用二:长生命周期保存数据   (免登陆)。

cookie的读和写

//写 (增,改) // document.cookie = "键=值"; // document.cookie = "name=ligen"; document.cookie = "pwd=666"; document.cookie = "name=tianmengxiang";

//读
// pwd=666; name=tianmengxiang 用分号+空格区分的字符串
// console.log(document.cookie);

let strCookie = document.cookie;
let arrCookie = strCookie.split("; "); //["pwd=666","name=tianmengxiang"];
for (let i = 0; i < arrCookie.length; i++) {
    let item = arrCookie[i].split("=");//[pwd=666]
    console.log(item[0], item[1]);
}

// 注意事项:使用cookie必须有服务器

cookie的生命周期

// cookie的生命周期: // 1.session会话级别 // document.cookie = "name=laowang"; // 2.长生命周期 // document.cookie="键=值;expires="+标准日期对象; let date = new Date(); date.setDate(date.getDate() + 7); document.cookie = "name=xiaohuanghuang;expires=" + date;

arguments的作用

// 1.              arguments:代表函数接收的实参伪数组
    // function fun() {
    //     // console.log(arguments);
    //     for (let i = 0; i < arguments.length; i++) {
    //         console.log(arguments[i]);
    //     }
    // }
    // fun(1, "heihei", true);
    
 //2.              arguments.callee:代表函数对象本身
     // function fun() {
    //     // console.log(fun);
    //     console.log(arguments.callee);
    // }

    // fun();

    // 有什么用?
    // 可以在递归中使用,当函数名改变的时候,不用改内部函数名

    //递归:一个函数直接或者间接的调用自己本身
    

prototype的概念以及作用

prototype是函数对象(通常只和构造方法连用)的一个属性,称为原型对象, 原型对象保存着所有该类实例化对象共享的属性和方法

function Student(id, name) {
        this.id = id;
        this.name = name;
        // this.study = function() {
        //     console.log("我最爱学习了");
        // }
    }

    Student.prototype.study = function () {
        console.log(this.name + ":爱学习");
    }

    Student.prototype.teacher = '小黄黄';

    let s1 = new Student(1, "老王");

    s1.teacher = "瑞瑞"; //原型对象上的属性和方法是不可以通过实例化对象去修改的
    //当实例化对象修改原型对象的属性时,其等价于创建了一个自定义属性                        
    delete s1.teacher; //删除添加的自定义属性
    s1.study();
    console.log(s1.teacher);

    Student.prototype.teacher = '大黄黄';
    let s2 = new Student(2, "薛依依");
    s2.study();
    console.log(s2.teacher);

为什么实例化对象可以访问所有的属性和方法?

//为什么实例化对象可以访问所有的属性和方法? // 通过原型图解释 //每一个实例化对象都可以直接访问自己new出来的属性, //每个实例化对象都拥有一个proto属性,该属性指向类的 //原型对象,所以实例化对象可以访问该类原型对象上的属性和方法

封装一个数组中求最大值

    let arr = [6, 5, 17, -4, 18, 9];
    Array.prototype.max = function() {
    let x = this[0];
    for (let i = 0; i < this.length; i++) {
        if (x < this[i]) {
            x = this[i];
        }
    }

    return x;
}

    console.log(arr.max());

解释apply,call和bind的异同?

1.都是用来修改this指向的函数 2.bind主要用来修饰匿名函数 3.apply和call主要修饰有名函数 4.apply的第二个参数是数组 5.apply和call相当于函数调用,bind只是生成了一个新的函数对象,并未调用该方法

继承的概念

继承概念

                    生物
            动物            植物
        人      狗
    学生    校长
大学生  小学生

父类派生给子类属性和方法,子类可以直接使用,
并且子类可以创建新的属性和方法。

作用:提高代码的复用性

原型继承
apply和call继承
混合继承
ES6继承

原型继承

JS里的继承主要依靠是的原型链。 让子类的原型对象的值, 等于另一个类型(父类)的实例,即实现了继承。

为什么子类的对象可以访问所有的属性和方法?

原型链,解释原型链
子类对象可以直接访问子类添加的属性,通过__proto__访问到子类原型上的方法
通过原型对象的指向,访问到父类实例化对象的属性
再通过父类实例化对象的__proto__,找到父类原型对象上的属性

原型继承的缺陷?

  1. 无法在子类对象构造时, 初始化父类派生给子类的属性

    1. 必须先实现继承关系,再为子类添加新的方法

    2. 一旦继承关系实现,子类原型对象的指向就不能再更改

typeof和instanceof的异同?

1. 都是用来判断数据类型的关键字
2. typeof用来判断内置基本类型, Number, string, Boolean
3. instanceof用来判断引用类型, 对象 instanceof 类型

apply和call的继承?

通过apply和call实现"继承" 作用:可以让子类对象在构造时,初始化父类派生给子类的属性 缺陷:无法继承原型对象上的方法和属性

    function Human(id, name) {
        this.id = id;
        this.name = name;
        // this.eat = function() {
        //     console.log("eat");
        // }
    }

    Human.prototype.eat = function() {
        console.log("eat");
    }

    function Student(id, name, score) {
        //借用构造方法实现"继承"
        Human.apply(this, [id, name]);
        this.score = score;
    }

    let s = new Student(1, "小明", 100);
    console.log(s.id, s.name, s.score);
    s.eat();

混合继承

// 混合继承:apply和call继承属性
//         原型对象继承方法
    function Human(id, name) {
        this.id = id;
        this.name = name;
    }

    Human.prototype.eat = function() {
        console.log("eat");
    }

    function Student(id, name, score) {
        Human.call(this, id, name); //属性的继承
        this.score = score;
    }

    Student.prototype = new Human(); //原型上方法的继承

    Student.prototype.study = function() {
        console.log("study");
    }

    let s = new Student(1, "小明", 100);
    console.log(s.id, s.name, s.score);
    s.study();
    s.eat();

es6继承?

  class Human {
        constructor(id, name) {
            this.id = id;
            this.name = name;
        }

        eat() {
            console.log("eat");
        }
    }

    class Student extends Human {
        constructor(id, name, score) {
            // 借用父类构造方法,且super必须放在第一行
            super(id, name);
            this.score = score;
        }

        study() {
            console.log("study");
        }
    }

    let s = new Student(1, "老王", 200);
    console.log(s);
    s.eat();
    s.study();

内置基本类型和引用类型在内存中存储的区别?

前提:内置基本类型与引用类型再内存中存储的区别 内置基本类型:只有一块栈空间,存储的是数值本身。

引用类型:有两块空间,一块栈空间,一块堆空间 栈空间存储的是堆空间的地址 堆空间存储的是真正的数值

 // 前提:内置基本类型与引用类型再内存中存储的区别
    // 内置基本类型:只有一块栈空间,存储的是数值本身。
    // let a = 123;
    // console.log(a);

    // 引用类型:有两块空间,一块栈空间,一块堆空间
    // 栈空间存储的是堆空间的地址
    // 堆空间存储的是真正的数值
    // let arr = new Array(1, 2, 3, 4, 5);

深拷贝与浅拷贝?

拷贝:用已有对象初始化一个新的对象

浅拷贝:只拷贝地址但是并不开辟空间,两个对象共享同一堆内存空间

深拷贝:开辟堆空间,且赋值

//深浅拷贝只针对于引用类型
    // let arr1 = [1, 2, 3]; //new Array(1,2,3);
    // 浅拷贝:只拷贝地址但是并不开辟空间,两个对象共享同一堆内存空间
    // let arr2 = arr1;

    // arr2[0] = 666;

    // console.log(arr1);
    // console.log(arr2);

    //------------------------------------
    // 深拷贝:开辟堆空间,且赋值
    // let arr1 = [1, 2, 3];
    // let arr2 = [];

    // for (let i = 0; i < arr1.length; i++) {
    //     arr2.push(arr1[i]);
    // }

    // arr2[0] = 666;

    // console.log(arr1);
    // console.log(arr2);

    function Student(id, name) {
        this.id = id;
        this.name = name;
    }

    //将调用对象拷贝一份作为返回值
    Student.prototype.copy = function() {
        let item = new Student(this.id, this.name);
        return item;
    }

    let s1 = new Student(1, "凢凢");
    let s2 = s1.copy();

    s1.id = 666;
    console.log(s1.id, s1.name);
    console.log(s2.id, s2.name);

本地及会话存储

localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem等
getItem(key):获取指定key所存储的value值
key(index)方法:返回列表中对应索引的key值
length属性:返回key/value队列的长度
removeItem(key)方法:从Storage中删除一个对应的键值对。
setItem(key,value)方法:将value存储到key指定的字段。
clear()方法:移除所有的内容
//增改
    //.a setItem
    // localStorage.setItem("name", "老王");
    // sessionStorage.setItem("age", 666);
    // b 点运算符
    // localStorage.age = 18;
    // c. 下标法
    // localStorage["gender"] = 'M';
    // localStorage.setItem("name", "刘磊");

    //查
    // a.getItem(key):返回key对应的value
    // console.log(localStorage.getItem("name"));
    // b.点运算符
    // console.log(localStorage.age);
    // c.下标法
    // console.log(localStorage["gender"]);

    //删
    // localStorage.removeItem("gender");

    //------------------------------------------------------
    // localStorage.setItem("data", '{"name":"老王","age":18}');
    // let json = JSON.parse(localStorage.getItem("data"));
    // console.log(json);

    //遍历所有键值对
    // for (let i = 0; i < localStorage.length; i++) {
    //     console.log(localStorage.getItem(localStorage.key(i)));
    // }

    localStorage.clear();

函数定义的方式?

函数定义的方式
    a.
    function fun() {
        console.log("heiheihei");
    }
    fun();

    b.
    let fun1 = function() {
        console.log("yingyingying");
    }
    fun1();

    c.
    let fun2 = new Function(参数,代码);
    let fun2 = new Function("a", "b", "console.log(a+b)");
    fun2(1, 5);
    fun2(2, 5);

自运行

自运行:一个函数在定义的时候,自动运行,主要针对于匿名函数.

// let fun = function(){

    // }

    // fun() == function(){}()

    // function() { 错误,思想正确但语法无法实现
    //     console.log("heihei");
    // }();

    //a.
    // (function() {
    //     console.log("heihei");
    // })();

    //b.官方推荐
    // (function() {
    //     console.log("heihei");
    // }());

    // c.通过运算符和关键字实现
    ! function() {
        console.log("heihei");
    }();

    void

    function() {
        console.log("haha");
    }();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级罗伯特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值