javascript 深度克隆(深度拷贝一个对象) prototype __ptoto__ consstructor
2015-10-09 22:11
861 查看
最近看到前端的面试题,是 关于深度克隆还有浅度克隆的
还有引用类型(数组和对象)按址传递,引用类型在值传递的时候是传递的地址,也就是说的按引用传递,对于引用传给函数的是变量的地址,
传进去的时候这时候就相当于有了一个变量的地址的拷贝,如果对这个拷贝重新赋值的话,是对原变量没有影响的,但是如果直接对传进去的变量(引用类型)直接操作的话就对外部的变量也会想用的改变;
说的简单一点就是基本类型传进去的是变量的拷贝,引用类型传进去的是变量的地址;
但是这两种传递方式实质是一样的:
先看第一个代码:
这样虽然传进去的是引用类型,但是对变量地址拷贝进行的改变,这样就和原来的引用没有关系了;
,看下面这个代码
看下面代码:
这样对传进去的变量直接操作就是也改变了外面的地址;
1>prototype本身上就是JavaScript的一个对象
2>每个函数都有一个prototype
3>通过prototype可以扩展JavaScript的内建函数
如果这个函数被用在创建自定义对象的场景中,我们称这个函数为构造函数;
当对象被实例化之后,构造函数会立即执行所包含的代码;
当new一个类的时候就开启了一个构造函数,例如下面的代码:
还有下面的代码:
注意:只有构造函数才有prototype实例化之后的是没有这个属性的;
就想是这样 就会报错
2.每个函数都有一个prototype,而这个prototype的constructor始终指向这个函数
alert(test.prototype.constructor === Test);
constructor 是始终指向原型函数,所以上面的判断返回的是true;
_proto_是指向其原型的对象的引用;用下面的代码简单验证一下:
__proto__能完成继承,下面代码解释:
![](https://img-blog.csdn.net/20151010151706554?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
看弹出的是:
![](https://img-blog.csdn.net/20151010152002394?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
再看下面的图:
![](https://img-blog.csdn.net/20151010152103654?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
就是利用这样连接原型链;
JavaScript按值传递和按引用传递:
JavaScript的基本类型一共五种包括(undefined,Null,boolean,Number,String)这几种都是按照值传递;还有引用类型(数组和对象)按址传递,引用类型在值传递的时候是传递的地址,也就是说的按引用传递,对于引用传给函数的是变量的地址,
传进去的时候这时候就相当于有了一个变量的地址的拷贝,如果对这个拷贝重新赋值的话,是对原变量没有影响的,但是如果直接对传进去的变量(引用类型)直接操作的话就对外部的变量也会想用的改变;
说的简单一点就是基本类型传进去的是变量的拷贝,引用类型传进去的是变量的地址;
但是这两种传递方式实质是一样的:
先看第一个代码:
var a=[], b={}, c={}; function foo(a,b,c){ var v1 = Array (1), v2 = [2,2], v3 = {"x":2}; } foo(a,b,c); console.log(a); console.log(b); console.log(c);
这样虽然传进去的是引用类型,但是对变量地址拷贝进行的改变,这样就和原来的引用没有关系了;
,看下面这个代码
var a = {'a':1}; var b = a; b.b = 2; if(a === b){ console.log(b); console.log(a); }这样修改b的值a会改变;
看下面代码:
var v1 = [] var v2 = {}; var v3 = {a:0}; function foo(v1, v2, v3) { v1.push (1); v2.a = 2; v3.a = 3; } foo(v1, v2, v3); alert (v1); // 1 alert (v2.a); // 2 alert (v3.a); // 3
这样对传进去的变量直接操作就是也改变了外面的地址;
javascript中的prototype属性和原生链:
1.什么事原型(prototype):
2>每个函数都有一个prototype
3>通过prototype可以扩展JavaScript的内建函数
如果这个函数被用在创建自定义对象的场景中,我们称这个函数为构造函数;
当对象被实例化之后,构造函数会立即执行所包含的代码;
当new一个类的时候就开启了一个构造函数,例如下面的代码:
function Person(Name){ this.name = Name; } Person.prototype={ getName:function (){return this.name;} }; var shang = new Person("Helios"); console.log(shang.getName());
还有下面的代码:
function MyFun(){ var name = "Helios", age = 21, sex = "男"; //只有在实例化之后 this.mother = "person"; //声明私有变量 this.father = "people"; var That = this; this.Name = function(){ console.log("Helios"); } function Other(){ console.log("123"); } } var fun = new MyFun; fun.name = "22"; console.log(fun.Name()); console.log(fun.age); console.log(fun.mother);
prototype:
用prototype制造JavaScript的内建函数:// 向JavaScript固有类型Array扩展一个获取最小值的方法 Array.prototype.min = function () { var min = this[0]; for (var i = 1; i < this.length; i++) { if (this[i] < min) { min = this[i]; } } return min; }; // 在任意Array的实例上调用min方法 console.log([1, 56, 34, 12].min()); // 1
注意:只有构造函数才有prototype实例化之后的是没有这个属性的;
function test(x,y){ this.x = x; this.y = y; } test.prototype.funX=function(){ alert(Test.x); } var Test = new test(5,5); Test.prototype.funY=function(){ alert("sd"); } Test.funY(); /*Test.funX(); alert(Test.x);*/ //test(1,1); alert(test.prototype.constructor === Test);
就想是这样 就会报错
构造器(constructor):
1.constructor始终指向创建当前的对象的构造(初始化)函数;2.每个函数都有一个prototype,而这个prototype的constructor始终指向这个函数
alert(test.prototype.constructor === Test);
constructor 是始终指向原型函数,所以上面的判断返回的是true;
原型链:
实例化的对象和原型都有一个原型,塑像的原型第父元素,父元素的原型是父亲的父亲;这样的一条链就构成了原型链;_proto_是指向其原型的对象的引用;用下面的代码简单验证一下:
var person =function(){} person.prototype.getinfo=function(){ alert("usename "+this.usename); } var Person = new person(); Person.usename = "shangyilong"; Person.getinfo(); alert(Person.__proto__ == person.prototype);
__proto__能完成继承,下面代码解释:
var shape={ getarea:function(){ return ("area : " + this.area); } } var Retal = { getEdge : function(){ return ("Edge : "+this.Edge); } } var options = { area : 4, Edge : 5 } alert(shape.__proto__ == Object.prototype); alert(options.getarea); alert(options.getEdge); Retal.__proto__ = shape; options.__proto__ = Retal; alert(options.getarea()); alert(options.getEdge());
看弹出的是:
再看下面的图:
就是利用这样连接原型链;
相关文章推荐
- js 两个日期之差
- 第 二 十 五 天 :解 析 JSP 的 软 件 简 单 配 置
- JS数组方法汇总 ARRAY数组元素的添加和删除
- 前端javascript模板
- js 函数
- 【转】JSTL 核心标签库 使用
- Jsp中的EL表达式
- {welcome to JS} 处理图像(翻转器)
- javaScript在私有的属性和方法
- Selenium+PhantomJS 爬取页面
- 纯JS实现fadeIn 和fadeOut
- javascript常用数组算法总结
- 10道javascript笔试题
- JS页面间传值
- JavaScript 面向对象之构造函数+成员函数详解
- iframe父子页面间通信总结
- 经典JavaScript正则表达式实战
- 一个通用的js动画函数
- js 循环json
- js如何去掉字符串中所有的逗号