—————————————————————————————————
- 对于typeof的一点补充、数据检测
- 数据检测constructor
- 进制转换
- 深拷贝探究
- 数组与类数组
- new和object.create()的区别
- 垃圾回收机制、内存变量、堆栈
- 数组扁平化的实现
- toString与value
—————————————————————————————————
1、对于typeof的一点补充、数据检测
之前的一篇文章~
组合继承、检测数据类型的几种方法、检测对象的属性是否在原型对象上等问题、页面出现空白问题产生的原因
虽然typeof对于null,对象,数组,正则都不能很好的判断,除了上篇文章检测数组的方法,还可以检测出null,通过 typeof
结合 !
就可以判断,具体代码如图!
2、关于数据检测 constructor
constructor 属性返回一个指向创建了该对象原型的函数引用。该属性的值是那个函数本身
1、constructor 不适合用来判断变量类型。因为它是一个属性,容易被伪造
function Father() {
this.name = "wyj";
}
function Father2() {
this.name = "sss";
}
Father.prototype.active = function () {
return "haha";
}
Father.prototype.sex = "girl";
Father2.prototype.sex = "boy";
var son = new Father();
console.log(son.constructor);
son.constructor=Father2;
console.log(son.constructor);
2、constructor 指向的是最初创建当前对象的函数,是原型链最上层的那个方法
function Animal() { }
function Cat() { }
Cat.prototype = new Animal;
function BadCat() { }
BadCat.prototype = new Cat
//cat animal function object
console.log((new BadCat).constructor === Animal); true
console.log((new BadCat).constructor === Cat);//false
console.log((new BadCat).constructor === Object);//false
console.log((new BadCat).constructor === Function);//false
console.log(Animal.constructor === Function);// true
3、可以根据返回的函数名来判断是什么类型,但是不能用于undefined和null,会报错
var num=2;
console.log(num.constructor);
var str="2d";
console.log(str.constructor);
var arr=[];
console.log(arr.constructor);
var obj={};
console.log(obj.constructor);
var reg=/^$/;
console.log(reg.constructor);
var sym=new Symbol;
console.log(sym.constructor);
var und=undefined;
console.log(und.constructor);
// var nu=null;
// console.log(nu.constructor);
3、进制转换
4、关于深浅拷贝
实现深拷贝方法有
1、json拷贝
2、递归拷贝
3、jquery.extend(target,obj1,obj2)拷贝
var obj={
name:"wyj",
sex:"girl",
hobby:["画画","旱冰"],
active:function(){
this.want="想要工作!";
return this.name+this.want;
},
boyfriends:null,
workbase:undefined,//工作地点
date:new RegExp('\\w+'),
today:[new Date()],
isNumber:NaN,
block:Infinity
}
//实现深拷贝
var a=JSON.stringify(obj);
var b=JSON.parse(a);
console.log(obj,b);
如图,对于正则,会转化为空对象,对于时间对象,会转换为字符串形式,undefined,函数不会被拷贝,对于NaN,Infinity,-Infinity会拷贝为null
function Father() {
this.name="wyj";
this.age="18";
this.active=function(){
return this.name+"在睡觉";
}
}
var son =new Father();
Father.prototype.add="测试一下";
Father.prototype.addFun=function ha(){}
var soncopy=JSON.parse(JSON.stringify(son));
console.log(son,soncopy);
如果对象是通过构造函数实现的,json深拷贝会丢失构造函数的原型对象上的所有属性和方法,会丢弃对象的constructor
准确无误的方法:递归
function deepcopy(obj) {
var result;
if (typeof (obj) == "object" && obj != null) {
if (obj instanceof RegExp || obj instanceof Date) {
result = obj;
}
else {
result = obj instanceof Array ? [] : {};
for (var i in obj) {
result[i] = deepcopy(obj[i]);
}
}
}
else {
result = obj;
}
return result;
}
截图是对之前那两个例子的测试
jquery方法实现深拷贝
1、undefiend值无法拷贝,可以拷贝原型上的值
2、需要引入jquery库
3、第一个参数为deep,为true时为深拷贝,不写默认为浅拷贝
var obj={
name:"wyj",
sex:"girl",
hobby:["画画","旱冰"],
active:function(){
this.want="想要工作!";
return this.name+this.want;
},
boyfriends:null,
workbase:undefined,//工作地点
date:new RegExp('\\w+'),
today:[new Date()],
isNumber:NaN,
block:Infinity
}
var c = $.extend(true,{}, obj);
c.hobby[0]="aaa";
console.log(obj, c);
5、Object.assign()
浅拷贝,不会拷贝原型上的属性或函数
var obj={
name:"wyj",
sex:"girl",
hobby:["画画","旱冰"],
active:function(){
this.want="想要工作!";
return this.name+this.want;
},
boyfriends:null,
workbase:undefined,//工作地点
date:new RegExp('\\w+'),
today:[new Date()],
isNumber:NaN,
block:Infinity
}
// var c = $.extend(true,{}, obj);
var c=Object.assign({},obj);
c.hobby[0]="aaa";
console.log(obj, c);
5、数组、类数组
1、数组和类数组都具有length属性
2、类数组具有数组的特征,但不具有数组的所有方法,本质为对象
2、常见的类数组:arguments、jquery、js获取dom元素,nodelist集合
3、构造类数组时,必须设置有length属性
<div>
<p>第一个
<div class="cla">
<span>hahah</span>
</div>
</p>
<p>第二个
<div class="cla">
<span>hbyebye</span>
</div>
</p>
</div>
<script src="../jquery/jquery.min.js"></script>
<script>
//jquery获取dom
console.log($(".cla"), $(".cla").length);
console.log($(".cla") instanceof Object);
console.log($(".cla") instanceof Array);
//原生dom
var cla = document.getElementsByClassName("cla");
console.log(cla, cla.length);
console.log(cla instanceof Object);
console.log(cla instanceof Array);
//arguments对象
function test(a,b,c){
console.log(arguments,arguments.length);
console.log(arguments instanceof Object);
console.log(arguments instanceof Array);
}
test(4,5,6);
</script>
类数组转换为数组的方法
六种方法
Array.from
方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象。
//两者转换
//第一种方法
Array.prototype.slice.call(arrayLike, start);
//第二种方法 arraylike要可遍历!!!
[...arrayLike];
//第三种方法:
Array.from(arrayLike);
引用别人的:
String 对象的方法 slice()、substring() 和 substr()(不建议使用)都可返回字符串的指定部分。slice() 比 substring() 要灵活一些,因为它允许使用负数作为参数。slice()与 substr() 有所不同,因为它用两个字符的位置来指定子串,而 substr() 则用字符位置和长度来指定子串。
数组转换为类数组,apply妙用
数组转换为类数组,apply妙用,apply,call,bind
6、new
和object.create()
的区别
1)new 继承原型和实例属性、方法
2)create 只继承原型对象上的属性和方法,但是可以通过第二个参数继承实例属性、方法
var fn = function (name) {
this.name = name;
this.sleep = function () { };
}
fn.prototype.sex = "boy";
var f1 = new fn();
var f2 = Object.create(fn.prototype, {
foo: {
writable: true,
configurable: true,
value: "hello"
},
// bar会成为所创建对象的访问器属性
bar: {
configurable: false,
get: function () { return 10 },
set: function (value) {
console.log("Setting `o.bar` to", value);
}
}
});
console.log(f1, f2);
8、数组扁平化的实现
数组扁平化
9、toString与valueOf的区别
对于数组
//valueof 与 tosting
console.log("toString","valueof");
//对象
var obj={};
console.log("obj",obj.toString());
console.log("obj",obj.valueOf());
//数组
var arr=[1,2,[3,4,[5,6]],7];
console.log("arr",arr.toString());
console.log("arr",arr.valueOf());
//正则
var reg=/^\d$/;
console.log("reg",reg.toString());
console.log("reg",reg.valueOf());
//字符串表达式
var str=0+'h';
var str1=1-"0";
console.log("str",str.toString());
console.log("str",str.valueOf());
console.log("str1",str1.toString());
console.log("str1",str1.valueOf());
//函数
var fn=function(){this.name="wyj";}
console.log("fn",fn.toString());
console.log("fn",fn.valueOf());
//布尔
var bool=true;
console.log("bool",bool.toString());
console.log("bool",bool.valueOf());