JS数据类型、call/apply、arguments

随记JS基础知识,加入个人理解。

JS数据类型
  • 基本类型:数值、字符串、布尔、null、undefined
    • 基本类型按值传递,赋值时开辟新的内存空间存储副本;值改变互不影响。
    • 存储在栈内存中、存储的是具体的值;其大小固定的。
  • 引用类型:对象(数组、函数等)
    • 引用类型,引用内存地址。
    • 存储在堆内存中,存储的栈内存地址;其大小不固定。

简单示例:

	// 基本数据类型
	var a=1;
	var b=a;
	a=2;
	// a=2 ; b=1;
	
	// 引用类型、常规赋值
	var a={name:"Joy"};
	var b=a;                       
	var c={d:b};
	a.name="Helo";
	// a.name="Helo"  ;   b.name="Helo"    c.d.name="Helo"; 

  可以看出将引用类型赋值给另一个变量时,引用类型的属性值发生改变则相关的变量的属性都会发生变化。

  再看这个示例:

	var a={name:"Joy"};
	var b=a;                       
	var c={d:b.name};
	a.name="Helo"
	// a.name="Helo"  ;   b.name="Helo"    c.d.name="Joy";

   给对象c的属性赋值的是基本数据类型b.name是字符串,所以开辟了新内存地址去存储属性d:"Joy"; a/b对象还是引用的属性name内存地址。

这样对于深、浅拷贝就有了简单说明:

基本数据类型开辟新内存地址进行存储;引用类型引用内存地址存储

  • 浅拷贝把对象中可枚举的属性复制一份给目标对象。 (如果属性还是引用类型,引用其内存地址,拷贝结束)
  • 深拷贝把对象中可枚举的属性复制一份给目标对象。 (如果属性还是引用类型,则继续遍历取出其中的属性递归处理:是基本类型则拷贝,引用类型继续递归处理…直到所有的属性按照基本类型数据拷贝给目标对象。而不是引用类型数据)

浅拷贝:

	var a={
		name:"li",
		age:23,
		other:{
			birthday:"1994009121123",
			address:"****"
		}
	};
	
	Object.assign(target,...source);      // 浅拷贝
	
	var b = Object.assign({},a);
	b.name="hua";
	b.other.birthday="201009123322";

	// a.name="li"    b.name="hua"
	// a.other.birthday="201009123322"         b.other.birthday="201009123322"
	// 浅拷贝逻辑
	for(let prop in a){
		b[prop] = a[prop];
	}

深拷贝:

	// 深拷贝逻辑
	function deepCopy(copyObj,target){
		for(let prop in copyObj){
			let value = Reflect.get(copyObj,prop);
			if(value== target){
				continue;             
			}
   			let isArray = Array.isArray(value);      // 先判断值是否为数组,
			if(typeof value == "object"&&!isArray){
					target[prop] = Object.create({});
					deepCopy(copyObj[prop],target[prop]);
				}else if(isArray){
					target[prop] = [];
					deepCopy(value,target[prop]);
				}else{
					target[prop] = value;
				}
			}
	}
	
	let obj = {
	  name:"li",
	  age:32,
	  hobby:["a","b"],
	  detail:{
	    birthday:'2019'
	  }
	}
	let obj_b = {};
	deepCopy(obj,obj_b);

对数组的处理,主要在于数组也是对象,所以处理数据时先判断值是否为数组。

Call()、Apply()

都是Function原型链上的方法;

说明:第一个参数指定函数执行上下文对象this指向;其他的都是执行参数。
区别:

  • call(context,arg1,arg2,...) ,参数不固定。
  • apply(context,[arg1,arg2,...]),两个参数,第二个为参数数组。

返回值:方法无返回值则返回undefined
功能说明:属性混入、继承,就是把这个对象的属性、方法传授给调用者。就不需要重复写了。

若没有第一个参数,则this绑定为全局对象 ;如果为严格模式use strict则为undefined
非严格模式下,指定nullundefined会自动指向全局对象。

call(context,arg1,arg2,…)

// 实现继承
function Person(name,age){
	this.name=name;
	this.age=age;
	
}
function Young(name,age){
	Person.call(this,name,age);
	this.feature="naughty";
  
}

console.log(new Young("大飞",32).name);       // output: "大飞"

// 绑定this上下文对象
let obj=[
	{
		name:"001",
		age:"12",
	},
	{
		name:"002",
		age:"23",
	}
];
for(let i=0;i<obj.length;i++){
	(function(index){
		this.print = function(){
			console.log("obj#"+index,this.name,this.age);	
		}
		this.print();
	}).call(obj[i],i);
}
// output:obj#0 001 12
//        obj#1 002 23

apply(context,[arg1,arg2,…])

可接收类数组对象,注意兼容性NodeList

// 向数组添加成员,一般我们使用for循环添加成员
var arr=[1,2,3];
var item=[4,5];
arr.push.apply(arr,item);
// arr:[1,2,3,4,5]

使用contact合并两个数组,返回的是一个新数组。

// 数值比较,多值比较麻烦
var min = Math.min(2,12,1,5);         // min:1 
var arr = [2,12,1,5];
var min = Math.min.apply(Math,arr);

当比较的数组值很多时,注意越界问题。超过最大参数可能会丢失。

什么叫类数组对象
 类数组对象须键值(key)为数值,否则数组值为undefined、必须有length属性,决定数组的长度。

let obj={
	1:"1",
	2:"2",
	4:"4",
	length:"6",	
}
Array.prototype.join.call(obj,"-");
// output: -1-2--4-
//下标0 / 3 / 5 值都为空值
arguments

是一个类数组对象。函数传参的参数对象,所有函数中可用的布局变量。

function TT(){
	console.log(arguments);
}
TT(1,"world",[3,4]);

在这里插入图片描述

转换为Array

var args = Array.prototype.slice.call(arguments);
// es5 
var args = Array.from(arguments);
var args =[...arguments];

// 使用Array的默认构造函数
var args = Array.apply(null,arguments);

在这里插入图片描述

属性

arguments.callee:指向当前执行的函数。
arguments[@@iterator]迭代器对象,包含参数索引。

function TT(){
	let obj = arguments[Symbol.iterator]();
	for(let item of obj){
		console.log(item);
	}
}
TT(1,"world",[3,4]);
// 1
// "world"
// [3,4]

使用typeof获取类型、返回object

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

heroboyluck

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

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

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

打赏作者

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

抵扣说明:

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

余额充值