最近看到前端的面试题,是 关于深度克隆还有浅度克隆的
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};这样修改b的值a会改变; 看下面代码:
var b = a;
b.b = 2;
if(a === b){
console.log(b);
console.log(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):
如果这个函数被用在创建自定义对象的场景中,我们称这个函数为构造函数;
当对象被实例化之后,构造函数会立即执行所包含的代码;
当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());
看弹出的是:
再看下面的图:
就是利用这样连接原型链;