JSON
什么是json?
- 特殊的字符串格式,本质是一个字符串
- 内部对象的key和value都用双引号包裹的字符串
- 跨平台主流数据传输格式
var str = "{'name':'张三','age':20,'height':'178cm'}"; // json格式 里面必须是双引号
JSON使用
| JSON.stringify | js对象或数组转成json字符串 | | —- | —- | | JSON.parse | josn字符串转换成对象或数组 |
var arr = [{name:"张安",age:20},{name:"李四",age:22},{name:"王五",age:23}];
var josnstr = JSON.stringify(arr);
console.log(josnstr);
// josnstr += "1";
// console.log(josnstr)
// JSON.parse : 转换的一定是一个纯的json数据
var newarr = JSON.parse(josnstr);
console.log(newarr);
JSON作用
- 前后端交互 主流数据
深拷贝
var obj1 = {
name:"张三",
age:20,
fn:function(){
console.log(111);
},
a:undefined
}
var obj2 = JSON.parse( JSON.stringify( obj1));
// var obj2 = obj1;
// obj2.age = 30;
console.log(obj1);
console.log(obj2);
// json 深拷贝有缺陷 ,会忽略掉 函数 undefined 及 map 和set
深拷贝
引用,解决引用问题 深拷贝
- 新创建一个对象或者是一个数组,开辟一个新的内存空间,把要拷贝数据加到新的对象或者数组里
深拷贝深层对象或者数组问题,通过递归循环创建新的对象或是数组
json深拷贝 缺点:忽略掉 function undefined map和set
//递归深拷贝
var obj1={
name:'张三',
age:20
}
console.log(obj1);
var obj2 = obj1;
var obj2 = {};
for(var key in obj1){
// obj2
// console.log(key,obj1[key])
// 把obj1里的键名和键值加入到obj2里
obj2[key] = obj1[key];
}
obj2.age = 40;
console.log(obj1);
1.简单版本的深拷贝函数
var obj = {
名字:"张三",
年龄:20
}
console.log(obj.年龄);
function deepCopy(obj1) {
var obj2 = {};
for (var key in obj1) {
// obj2
// console.log(key,obj1[key])
// 把obj1里的键名和键值加入到obj2里
obj2[key] = obj1[key];
}
return obj2;
}
var obj1 = {
name: "张三",
age: 20
}
var obj2 = deepCopy(obj1);
obj2.age = 30;
console.log(obj1);
function deepCopy(obj1) {
// var obj2 = {};
// var obj2 = [];
// 根据传入的数据自动生成数组或者是对象
var obj2 = Object.prototype.toString.call(obj1)==="[object Array]"?[]:{};
for (var key in obj1) {
// 把obj1里的键名和键值加入到obj2里
obj2[key] = obj1[key];
}
return obj2;
}
// var arr = [1,2,3];
var obj = {name:"张三",age:20}
var newarr = deepCopy(obj);
console.log(newarr);
// 3.多层数据及对象的问题
var obj = {
name: "张三",
hobby: {
name1: "篮球",
name2: "足球"
}
}
function deepCopy(obj1) {
// var obj2 = {};
// var obj2 = [];
// 根据传入的数据自动生成数组或者是对象
var obj2 = Object.prototype.toString.call(obj1) === "[object Array]" ? [] : {};
for (var key in obj1) {
// 把obj1里的键名和键值加入到obj2里
obj2[key] = obj1[key];
}
return obj2;
}
var obj2 = deepCopy(obj);
// console.log(obj2);
// obj2.name = "李四";
obj2.hobby.name1 = "乒乓球";
console.log(obj2);
console.log(obj);
```javascript
// 多层对象或者数组如何深拷贝 ?
function deepCopy(obj1) {
var obj2 = Object.prototype.toString.call(obj1) === "[object Array]" ? [] : {};
for (var key in obj1) {
// 分成2种情况处理 1.简单数据 直接赋值给新的 obj2 2.复杂数据类型还要重新生成一个单独地址的数组或者是对象
// 判断循环出来的属性是否是自身属性 ,不需要处理原型及原型链上的属性和方法
if (obj1.hasOwnProperty(key)) {
if (typeof obj1[key] === "object") {
// 复杂数据类型 数组、对象
obj2[key] = deepCopy(obj1[key]);
} else {
obj2[key] = obj1[key];
}
}
}
return obj2;
}
Object.prototype.height = "178cm"; // 原始的对象上添加height属性
var obj1 = {
name: "张三",
age: 20,
hobby: {
name1: "篮球",
name2: "足球"
}
}
<a name="XxyGg"></a>
## 创建对象
```javascript
var obj={
name="张三"
}
var obj=new Object();
obj.name = "张三";
function ddd(name,age){
var obj={};
obj.name=name;
obj.age=age;
return obj;
}
var obj = ddd("张三",20)
function mynew(name,age){
var obj = {};
var res = Person.call(obj,name,age);
obj.__proto__ = Person.prototype;
// 如果没有返还,那么就返还this 也就是这个对象 。 如果有返还就返还用户返还的值
if(typeof res == "undefined"){
return obj;
}else{
return res;
}
}
// console.log(zhnangsan);
var zhangsan = mynew("张三",20);
console.log(zhangsan);
// zhangsan.fn();
create创建对象
对象的属性是可控制的
var obj =Object.create({name:'zhangsan',age:20})
console.log(obj);
__proto__ 和 [[prototype]] 是一样的。 下划线 _ [[]] 书写私有属性,不希望直接更改。
obj.__proto__.name = "" //不规范
var obj = Object.create(null,{
name:{
value:"张三",
writable:true, // 配置对象属性可写 ;
enumerable:true, // 可枚举 是否可以被循环
configurable:true // 可配置 删除对象属性
},
age:{
value:20,
writable:true,
enumerable:true,
configurable:true
}
})
console.log(obj);
//writable:是否可写;默认不可写;
obj.name = "李四";
console.log(obj);
//enumerable : 是否可以循环 ,默认是false 不可枚举,不可循环
for(var key in obj){
console.log(key);
}
//configurable : 是否可配置 ,默认是false 不可配置 删除属性 ;
delete obj.name;
console.log(obj);
var obj = Object.create(null, {
name: {
// getter
get: function () {
console.log("调用了get函数");
// 获取属性值的时候 自动调用get方法
return "张三";
},
// setter
set: function (newvalue) {
// 设置属性的时候会自动调用set方法
console.log("修改了", newvalue)
},
configurable: true,
enumerable: true
}
})
// console.log(obj);
// obj.name; // 获取name值 ,调用get函数
setTimeout(function () {
obj.name = "李四"; // 设置name的值 ;调用set 函数
}, 2000);
defineproperty
- 创建一个可控的对象
修改一个对象为可控制对象 ```javascript var obj = { name:”张三”, age:20 }
function observe(obj){ for(var key in obj){ var val = obj[key]; Object.defineProperty(obj,key,{
get:function(){ console.log("get"); return val; },
set:function(newvalue){
if(val!=newvalue){ val = newvalue; } }, configurable:true, enumerable:true }) } } observe(obj); console.log(obj);
<a name="zeedS"></a>
## 数据驱动
```javascript
<div id="app">
fdsafds{{message}}fdafda
</div>
<script>
// var vm = new Vue({
// el:"#app",
// data:{
// message:"数据"
// }
// })
// console.log(vm.$data);
// 一、在指定范围内渲染数据 ,初次渲染:根据数据把数据里的内容渲染到视图上;
var data = {
message:"我的数据"
}
// 在指定范围内查找 {{message}} 字符;
var APPEle = document.querySelector("#app");
var str = APPEle.innerHTML;
// console.log(str);
// 通过正则查找 {{}} 的内容
// var str = "fdafdsa{{message}}fdafda"
// () 分组 [1-30] 集合 {1,5}
// ? + {1,}
var reg = /\{\{([^{}]+)\}\}/;
if(reg.test(str)){
console.log("有大花括号");
// {{message}}
var $1 = RegExp.$1;
console.log($1);
// console.log(RegExp.$2);
var message = data[$1];
// console.log(message);
// {{message}} ---->message : 我的数据
APPEle.innerHTML = APPEle.innerHTML.replace(reg,message);
}
// 二、再次渲染;
// 把数据观察起来
// 死循环: get的触发条件是 data['message'] ,当触发 get的时候 会返还 data['message']
var val = data['message'];
Object.defineProperty(data,"message",{
get:function(){
console.log("get");
return val;
},
set:function(newvalue){
console.log("set");
// 监听到数据改变之后 ,获取最新的数据 ,把旧的数据替换掉就可以了
var oldvalue = message;
console.log(oldvalue);
// 通过replace 把旧数据替换成 新的修改的值;
APPEle.innerHTML = APPEle.innerHTML.replace(oldvalue,newvalue)
if(val!=newvalue){
val = newvalue;
}
},
configurable:true,
enumerable:true
})
console.log(data);
</script>