js的数据类型:
5个基本数据类型,1个对象object
- string
- number
- null
- undefind
- boolean
- 对象object(函数也是object)
(内存是暂时性的,并不是永久性的)
基本数据类型按值存储,存在栈内存中
//栈内存
var a = 1;
var b = a;
var b = 2;
consloe.log(a) //1
对象类型按地址存储,存在堆内存中
//堆内存
var obj = {
name:‘张三’
};
var obj2 = obj;
var obj2 = {
name:'李四
};
consloe.log(obj.name) //李四
基本类型的存储指向不是同一个地址,对象的存贮都是指向同一个地址
创建对象:
- new
var obj = new Object();
obj.name = '孙悟空';
obj1['age'] = 18;
console.log(obj.name) //孙悟空
- 字面量
var obj = {
name:'aa',
age:18,
say:function(){}
}
var obj2 = {
name:'aa',
age:18,
say(){}
}
- 工厂模式(缺点:instanceof只能判断他是object)
function Person(pname,page){
var obj = new Object();
obj.name = pname;
obj.age = page;
return obj;
}
var p1 = Person('李四',19);
console.log(p1.name)//李四
console.log(p1 instanceof Object)//true
console.log([1] instanceof Object)//true
console.log([1] instanceof Array)//true
在 JavaScript 中,判断一个变量的类型尝尝会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”。这就需要用到instanceof来检测某个对象是不是另一个对象的实例。
另外,更重的一点是 instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型。
例如:
function Foo(){}
Foo.prototype = new Aoo();//JavaScript 原型继承
var foo = new Foo();
console.log(foo instanceof Foo)//true
console.log(foo instanceof Aoo)//true
上面的代码中是判断了一层继承关系中的父类,在多层继承关系中,instanceof 运算符同样适用。
又如:
console.log(Object instanceof Object);//true
console.log(Function instanceof Function);//true console.log(Number instanceof Number);//false
console.log(String instanceof String);//false
console.log(Function instanceof Object);//true
console.log(Foo instanceof Function);//true
console.log(Foo instanceof Foo);//false
- 构造函数(instanceof可以看出是谁造出来的,缺点浪费资源)
每个构造函数都有一个prototype属性每一个prototype原型对象都有一个constructor(构造函数)属性。 这个属性指向prototype属性所在的函数
function Persons(pname,page){
this.name = pname;
this.age = page;
this.say(){
consloe.log('我叫'+this.name)
}
}
var myp = new Persons('李四',19);
var myp2 = new Persons('李四',19);
console.log(myp.name)//李四
console.log(myp instanceof Persons)//true
console.log(myp.say = myp2.say)//false,在堆内存创建了两个不同地址的函数
- 原型方法(节省资源,缺点:改了一个,都会跟着改)
function Cat(cname,cage){}
Cat.prototype.name = '滚滚';
Cat.prototype.age= 3;
Cat.prototype.friends = ['花花']
Cat.prototype.play= function(){
console.log('滚滚最喜欢玩毛线球')
};
var cat1 = new Cat();
var cat2 = new Cat();
cat1.friends.push('小白');
console.log(cat2.friends)//['花花',小白]
console.log(cat1,name);
cat1.play()
console.log(cat1,play === cat2.play);//true,在堆内存创建了一个地址的函数
继承
我们所创建的每个函数都有一个类型(prototype)属性是一个指针,指向一个对象 。
每一个prototype原型对象都有一个constructor(构造函数,也称构造器)属性这个属性指向prototype属性所在的函数 。
proto :每个实例对象都包含一个__proto__属性该属性指向构造函数的prototype原型对象
- 原型继承(缺点:改了一个其他的也会跟着改变)
将原型链作为实现继承的主要方法,其基本思想是利用原型让一个对象类型继承另一个对象类型的属性和方法。
//人类
function Person(){
this.head= 1;
this.foot = 2;
this.color = ['red']
}
//学生类
function stu(){
this.name= '学生';
}
//原型链继承:子构造函数的prototype等于父构造函数的实例
Stu.prototype = new Person()
var stu1 = new Stu();
stu1.color.push('blue')
console.log(stu1.name)//学生
console.log(stu1.head)//1
console.log(stu1.color)//['red','blue']
//缺点:改了一个其他的也会跟着改变
var stu2 = new Stu();
console.log(stu2.color)//['red','blue']
- 构造函数继承(解决了改了一个其他的也会跟着改变这个问题,缺点:只继承了父函数的属性,并继承不了构造函数上面的方法)
在子构造函数调用父构造函数,使用call()*(一个个传参)*和apply()(*数组,类数组对象。整体传参)*方法调用
例1:
//call和apply都可以改变this值
window.name ='孙悟空';
var bird = {
name:'鸟',
fly(){
console.log(this.naem + '会飞')
}
}
bird.fly.call()// 孙悟空会飞
var pig = {
name: '猪'
}
bird.fly.call(pig)//猪会飞
bird.fly.apply(pig)//猪会飞
例2:
//人类
function Person(){
this.head= 1;
this.foot = 2;
this.color = ['red']
}
Person.prototype.eat = function(){
consloe.log('今天吃了吗')
}
//构造函数继承:在子构造函数调用父构造函数
//学生类
function stu(){
Person.call(this) //此处this指向var stu1 = new Stu()
this.name= '学生';
}
//Stu.prototype = new Person();
var stu1 = new Stu();
stu1.color.push('blue')
console.log(stu1.name)//学生
console.log(stu1.head)//1
console.log(stu1.color)//['red','blue']
var stu2 = new Stu();
console.log(stu2.color)//['red']
stu2.eat();//报错,只继承了父函数的属性,并继承不了构造函数上面的方法
- 构造函数+原型继承(解决了所有问题)
//人类
function Person(){
this.head= 1;
this.foot = 2;
this.color = ['red']
}
Person.prototype.eat = function(){
consloe.log('今天吃了吗')
}
//构造函数继承:在子构造函数调用父构造函数
//学生类
function stu(){
Person.call(this) //此处this指向var stu1 = new Stu()
this.name= '学生';
}
Stu.prototype = new Person();
Stu.prototype.constructor = Stu;
var stu1 = new Stu();
stu1.color.push('blue')
console.log(stu1.name)//学生
console.log(stu1.head)//1
console.log(stu1.color)//['red','blue']
var stu2 = new Stu();
console.log(stu2.color)//['red']
stu2.eat();
console.log(stu2.__proto__ == Stu.prototype)//true
转载:https://blog.csdn.net/beLaity/article/details/106727571