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__,找到父类原型对象上的属性
原型继承的缺陷?
-
无法在子类对象构造时, 初始化父类派生给子类的属性
-
必须先实现继承关系,再为子类添加新的方法
-
一旦继承关系实现,子类原型对象的指向就不能再更改
-
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"); }();