javaScript 知识点回顾

很长一段时间没看js书籍了,最近抽点时间,回顾一些js基础的知识点,写了半天,朋友问个问题,解决一下bug,再回来写,都没了,又从新写。

(一)javaScript 浅拷贝与深拷贝

1:简单的数据类型

它们的值占据了内存中固定大小的空间和位置,并被保存在栈内存中。当一个变量向另一个变量赋值基本类型的值,会创建这个值的一个副本,还有就是不能给基本数据类型的值添加属性

var a = 1;
var b = a;
a.attr = 'ciyt';
console.log(a.attr)//undefined
VM1600:4 undefined复制代码

上面代码中a就是简单数据类型(Number),b就是a的副本,它们两者都占有不同位置但相等的内存空间。

2:复杂数据类型

复杂数据类型的引用赋值,一般指向的是统一个对象,因为他们的引用指针是一样的,赋值的其实是内存里面的地址指针。

var obj = {
	name:'liu',
	age:'28'
}
var obj2 = obj;
obj2.sex="boy";
console.log(obj);
console.log(obj2);
VM1733:7 {name: "liu", age: "28", sex: "boy"}
VM1733:8 {name: "liu", age: "28", sex: "boy"}
复制代码

我们可以看到obj赋值给obj2后,当我们给一个obj2对象的添加属性值,两个对象都发生了改变,究其原因局势因为obj和obj2这两个变量都指向同一个指针,赋值只是复制了指针,所以当我们改变其中一个的值就会影响另外一个变量的值。

这段代码就是我们常说的 浅拷贝,改变其中一个对象,另外一个对象也会改变。

下面我们来讲解一下深拷贝的方法,分数组【Array】和对象【Object】

数组

对于数组我们可以使用slice()concat()方法来解决上面的问题

var arry = [1,2,'a'];
var arry2 = arry;
arry2.push('b');
console.log('arry',arry)
console.log('arry2',arry2)
VM1974:4 arry (4) [1, 2, "a", "b"]
VM1974:5 arry2 (4) [1, 2, "a", "b"]
复制代码

slice()方法:

var arry = [1,2,'a'];
var arry2 = arry.slice(0);
arry2.push('b');
console.log('arry',arry)
console.log('arry2',arry2)
VM2057:4 arry (3) [1, 2, "a"]
VM2057:5 arry2 (4) [1, 2, "a", "b"]
复制代码

concat()方法:

var arry = [1,2,'a'];
var arry2 = arry.concat();
arry2.push('b');
console.log('arry',arry)
console.log('arry2',arry2)
VM2076:4 arry (3) [1, 2, "a"]
VM2076:5 arry2 (4) [1, 2, "a", "b"]
复制代码

对象

我们可以创建一个新对象 new Object() 或者封装一个深度拷贝的函数

var obj = {
	name:'liu',
	age:'28'
}
var obj2 = obj;
obj2.sex="boy";
console.log('obj',obj);
console.log('obj2',obj2);
VM446:7 obj {name: "liu", age: "28", sex: "boy"}
VM446:8 obj2 {name: "liu", age: "28", sex: "boy"}
复制代码

new Object()

var obj = {
	name:'liu',
	age:'28'
}
var obj2 = new Object();
obj2.name="liu";
obj2.age="28";
obj2.sex="boy";
console.log('obj',obj);
console.log('obj2',obj2);
VM508:9 obj {name: "liu", age: "28"}
VM508:10 obj2 {name: "liu", age: "28", sex: "boy"}
复制代码

封装一个deepCopy函数

var obj = [1,2,'a'];
function deepCopy(obj){
	var newObj = obj instanceof Array ? [] : {};
	for(var item in obj){
		var temporary = typeof obj[item] == 'Object' ? deepCopy(obj[item]) : obj[item];
		newObj[item] = temporary;
	}
return newObj
}
var obj2 = deepCopy(obj);
obj2.push('b');
console.log('obj',obj);
console.log('obj2',obj2);
VM1154:12 obj (3) [1, 2, "a"]
VM1154:13 obj2 (4) [1, 2, "a", "b"]
复制代码

var obj = {
	name:'liu',
	age:'28'
};
function deepCopy(obj){
	var newObj = obj instanceof Array ? [] : {};
	for(var item in obj){
		var temporary = typeof obj[item] == 'Object' ? deepCopy(obj[item]) : obj[item];
		newObj[item] = temporary;
	}
return newObj
}
var obj2 = deepCopy(obj);
obj2.sex = 'boy';
console.log('obj',obj);
console.log('obj2',obj2);
VM1222:15 obj {name: "liu", age: "28"}
VM1222:16 obj2 {name: "liu", age: "28", sex: "boy"}
复制代码

(二)jsonp原理

首先JSON是一种基于文本的数据交换方式,或者叫做数据描述格式,另外一种常见的是XML格式,当一个网页在请求JavaScript文件时则不受是否跨域的影响,凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>所以我们这里运用了script标签的跨域能力,让它用一个callback函数包裹着一段JSON格式的数据,当该数据返回到前端页面的时候,我们再执行这个函数就可以把数据读取出来

前端代码

jsonp.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>What's jsonp</title>
    </head>
    <body>
        <button onclick="jsonpServer('jsonp.php')">JSONP</button>
    </body>
    <script>
        function jsonpServer(url) {
            var script = document.createElement("script");
            script.setAttribute("type", "text/javascript");
            script.setAttribute("src", url);
            document.body.appendChild(script);
        }   
        function JSON_CALLBACK(data) {
            console.log(data);
        }
    </script>
</html>复制代码

后端代码

jsonp.php
<?php
$data = '[{"id":"1","name":"wsscat"},{"id":"2","name":"asw"}]';
$data = "JSON_CALLBACK(" . $data . ")";
echo $data;
?>复制代码

jQuery 的Ajax写法

$.ajax({
    url:'index.php',
    type:'get',
    dataType:'jsonp',
    //jsonp:'JSON_CALLBACK',
    jsonpCallback:'JSON_CALLBACK',
    success:function(data){
        console.log(data)
    }
})
复制代码

后端代码

<?php
    $data = '[{"id":"1","name":"wsscat"},{"id":"2","name":"asw"}]';
    $data = "JSON_CALLBACK(" . $data . ")";
    echo $data;
?>复制代码

(三)JavaScript 中的 call 与 apply 继承方法

call的意思就是把Animal构造的方法应用到cat这个对象身上,也就是Animal的属性创建到了cat里面,所以cat就继承了Animal的方法

function Animal(a, b) {
    this.type = 'Animal'
    this.behavior = function(){
        console.log(this.type+" is running")
    }
}

function cat(a, b) {
    this.name = 'goodCat'
    //这里call的意思就是把Animal的方法应用到cat这个对象身上
    //所以cat就继承了Animal的方法
    Animal.call(this);
}

console.log(new cat())VM2223:15 cat {name: "goodCat", type: "Animal", behavior: ƒ}behavior: ƒ ()name: "goodCat"type: "Animal"__proto__: Object复制代码

call实现多重继承 (ps:我们可以继承多个构造函数,这就是多重继承)

function Animal(a, b) {
    this.type = 'Animal'
    this.behavior = function(){
        console.log(this.type+" is running")
    }
}

function ageCat(a, b) {
    this.age = 0
}

function cat(a, b) {
    this.name = 'goodCat'
    //这里call的意思就是把Animal的方法应用到cat这个对象身上
    //所以cat就继承了Animal的方法
    Animal.call(this);
	//这里call的意思就是把ageCat的方法应用到cat这个对象身上
    //所以cat就继承了ageCat的方法
    ageCat.call(this);
}

console.log(new cat())VM2350:22 cat {name: "goodCat", type: "Animal", behavior: ƒ, age: 0}age: 0behavior: ƒ ()name: "goodCat"type: "Animal"__proto__: Object复制代码

apply与call的区别

其实apply和call这两个方法基本上是差不多的,区别在于call的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments(即传给构造函数的参数)。

继续优化继承

如果构造函数this绑定太多属性(比如一些共同方法),在实例化后会造成浪费,为此我们一般会使用原型链来优化,但是使用原型链之后我们的apply和call的继承方法就会失效
为此我们一般使用混合的写法,使用原型链和(apply或者call)方法进行继承
具体两句话
让子的原型链指向父的实例(父实例化的对象)
cat.prototype = new Animal();
让父的属性创建在子的this上
Animal.call(this, type)
整体代码如下,那么就会让父原型链的属性和this上的属性都得到继承

function Animal(type) {
    this.type = type
    this.behavior = function() {
        console.log(this.type + " is running")
    }
}
Animal.prototype.action = function() {
    console.log("running")
}

function cat(name, type) {
    this.name = name
    Animal.call(this, type)
}

cat.prototype = new Animal();
console.log(new cat('xiaohong', 'beautiful'));
(new cat('xiaohong')).action() //runningVM2490:17 cat {name: "xiaohong", type: "Animal", behavior: ƒ}behavior: ƒ ()name: "xiaohong"type: "Animal"__proto__: Animal复制代码

(四)sessionstorage,localstorage和cookie

cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。

sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。数据有效期不同,
sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;
localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;
localStorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。

总结:

  • localStorage没有过期时间,只要不clear或remove,数据会一直保存。
  • sessionStorage 针对一个session进行数据存储,生命周期与session相同,当用户关闭浏览器后,数据将被删除。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值