内置对象
- js提供的已经定义好的对象
- Array,Date,Boolean,RegExp,String,Number(常用)
- 同时js定义好了对应的一些构造函数
- 字符串,数字等基础类型数据是没有属性和方法的
- ??那么我们平时创建了一个字符串(非字符串对象)的时候,为什么可以调用他的length,indexOf的美好属性或方法??
- 上面问题的答案就是:包装对象
包装对象
- 当我们去调用字符串,数字,布尔值这三种基础数据类型的属性和方法的时候,他们本身是不具备属性和方法的,但是js内部,会自动的去调用他们对象的构造函数,然后把他们的值作为参数进行传入,然后执行对应属性或方法,并把结果进行返回
- 包装对象一个有三个:
string,Number,Boolean
方法
toString()
- Object对象prototype下的一个方法
- 所有对象都继承该方法
- toString()自定义改写
Array.prototype.toString = function() {
var result = 0;
for (var i=0; i<this.length; i++) {
result += this[i];
}
return result;
}
alert([1,2,3]);
function Person() {
}
// Person.prototype = new Object();
var p1 = new Person();
console.log(p1);
hasOwnProperty()
- 判断某个属性(方法)是否是某个对象自有的,就是非原型链上的
function Person() {
this.name = 'motao';
}
Person.prototype.x = 100;
var p1 = new Person();
console.log( p1.hasOwnProperty('name') );
console.log( p1.hasOwnProperty('x') );
constructor
- 属性:返回某个对象的构造函数
- 可以重写~
var a = [1,2,3];
// a.constructor = 1;
console.log(a.constructor == Array);
instanceof
- 运算符
- 判断一个对象是否是某个构造函数的实例化对象
var arr = [1,2,3];
console.log(arr instanceof Array);
继承
function DragLimit(element) {
// 调用Drag函数,并把Drag中this指向DragLimit的this
Drag.call(this, element);
}
- 如果我们是通过赋值的形式进行继承的话,那么会有问题,因为现在是对象赋值,那么DragLimit.prototype的修改会影响Drag.prototype
- 我们可以把Drag.prototype中的属性和方法一个个的赋值给DragLimit.prototype
- 为了方便,我们可以使用forin来批量动态的处理这些属性和方法
- forin不只是会把Drag.prototype自身的属性循环出来,还会把一些原型链上的属性和方法也循环出来
- 我们也可以 DragLimit.prototype = new Drag();
- ES6的话可以更方便的解决这个问题
class DragLimit extends Drag {
//extends 可以继承 Drag的所有,包括原型链上的
//然后在这里可以直接修改DragLimit原型上的属性(方法),并且不会随之改掉它所继承的Drag的原型上的属性(方法);
this.move {
}
}
类式继承
直接克隆,但是如果对象下面的属性包含对象的话,传递的是地址
当改变克隆到的新对象的值得时候,也会改变原有对象的值
<script>
/*
* 类式继承
* */
function Person() {
this.name = 'motao'
}
Person.prototype.eat = function() {
console.log('eat');
};
function Teacher() {
Person.call(this);
}
// 引用了
// Teacher.prototype = Person.prototype;
/**
* 让Teacher的prototype指向Person的一个实例对象,这样的话Teacher的prototype和Person的prototype就没有直接的引用关系,但是因为Teacher的prototype是Person的一个实例,那么Teacher的prototype自动会查找Person的prototype
*
* 通过Teacher的prototype可以找到Person的prototype下,但是Teacher的prototype和Person的prototype又没有直接的关系
*/
Teacher.prototype = new Person();
var mt = new Teacher();
console.log(mt);
mt.eat();
// mt.eat => mt.__proto__.eat => Teacher.prototype.eat => new Person().eat => new Person().__proto__.eat => Person.prototype.eat
</script>
graph LR
Teacher.prototype.eat-->new Person<>.eat
new Person<>.eat-->new Person<>.__proto__.eat
new Person<>.__proto__.eat-->Person.prototype.eat
原型继承
<script>
/*
* 和类式继承有点像
* */
var obj = {
x: 100
};
function Foo() {}
Foo.prototype = obj;
var obj2 = new Foo();
console.log(obj2.x);
</script>
深度继承
通过一个个的把原型的属性(方法)的值传给新建的一个函数extend里的newObject,并且返回,从而在深度继承的时候 var 新对象 = new extend(要继承的对象)
改变新的值得时候 不会改变原有的值
<script>
var obj1 = {
x: 10,
y: 20,
attr: {a: 1},
arr: [1,2,3],
z: null
};
// var obj2 = {};
// for (var property in obj1) {
// obj2[property] = obj1[property];
// }
// console.log(obj2);
// obj2.x = 100;
// console.log(obj2);
// console.log(obj1);
// obj2.arr 和 obj1.arr 是同一个地址
// obj2.attr.b = 2;
// console.log(obj2.attr);
// console.log(obj1.attr);
var obj2 = extend(obj1);
console.log(obj2);
obj2.attr.b = 2;
console.log(obj2.attr);
console.log(obj1.attr);
function extend(originObject) {
// 根据originObject的原始类型来对新对象进行对应的初始化,保证进来什么格式出去就是什么格式
var newObject = Array.isArray(originObject) ? [] : {};
for (var property in originObject) {
// 如果当前数据是对象的话,那么就需要进行深度克隆
// 注意:typeof来判断数据类型是有一个小的问题的,null的typeof结果也是object,所以需要排除null值的深度克隆
if (typeof originObject[property] == 'object' && originObject[property] !== null) {
// 核心:递归克隆
newObject[property] = extend(originObject[property]);
} else {
newObject[property] = originObject[property];
}
}
return newObject;
}
</script>
注意
- 如果我们尝试给字符串、数字、布尔值增加自定义的属性和方法的时候,是无效的
- 当一个字符串被申明以后,其值就不会发生改变,除非重新覆盖,所以我们把字符串称为字符串常量
原型链
(查找c的话)
(person是me的构造函数)
me.c --> me.__proto__.c
me.__proto__.c --> me.__proto__.__proto.c
||
me.c --> person.prototype.c
person.prototype.c --> person.prototype.__proto__.c
||
me.c --> person.prototype.c
person.prototype.c --> object.prototype.c
网友评论