文章目录
对象的创建方法
var obj = {}
plainObject 对象字面量/对象直接量- 构造函数
- 系统自带的构造函数
new Object()
- 自定义函数
new FunctionName()
- 系统自带的构造函数
自定义函数用大驼峰式命名 (所有首字母大写)
构造函数内部原理
- 在函数体最前面隐式加上this={}
- 执行this.xxx = xxx;
- 隐式的返回this
也可以传参
function Car(number){
// this = {};
this.date = 2020;
this.number = number;
//return this;
}
new car1 = new Car(1);
包装类
- new Number()
- new String()
- new Boolean()
原始类型没有 属性和方法
调用时实际上自动变成包装类
//包装类
var a = 1;
a.abc = 2;
// 不忍心报错 自动执行
// new Number(1).len = 2; delete 执行完又删除了
console.log(a.len); // undefined
// 发现访问属性又自动创建 new Number(4).len 是空的
字符串有 .length 属性
过程和上面一样
var str = 'abcd';
str.length = 2;
// nwe String('abcd').length = 2; delete
console.log(str); // 4
// new String('abcd').length 本身这个属性是存在的
ps. 渡一 《对象,包装类(下)》后半部分练题
原型
.prototype – 原型 是祖先
Person.prototype.name= 'hello';
function Person{
}
var a = new Person();
console.log(a.name); // 输出 hello 继承自原型
原型也是对象 可以这样写
Person.prototype = {
name : 'hello'
}
...
方别写很多
但稍微有区别 后面提到
定义
原型是function对象的一个属性,定义了构造函数 制造出的 对象的公共祖先
通过该构造函数产生的对象可以继承该原型的属性和方法
原型也是对象
功能
减少代码重复
共同部分放进原型中
修改原型
增 删 改 查
只能直接操作prototype操作
不能通过子元素操作
function Father(){
this.num = 1;
}
var father = new Father();
Son.prototype = father;
function Son(){
}
var son = new Son();
son.num = 2;
//son.num ++; 同
console.log(father.num); // 1
相当于给son新添加了num属性
father中的属性没有修改 也 没法修改(误)
但这种可以
function Father(){
this.num = 1;
this.say = {
name : 'niko'
}
}
var father = new Father();
Son.prototype = father;
function Son(){
}
var son = new Son();
son.say.name = 'dio'; // 二次调用 .name
console.log(son.say.name); // dio
成功修改 只能修改方法中的属性 相当于二次调用
constructor
系统自带原型有 constructor 属性
返回构造函数
但可以手动更改
_proto_
_proto_
指向原型
连接原型和子对象
找不到属性后 找_proto_中的属性
_proto_
默认储存的原型
但可以修改
两种写法区别
在二次修改时产生区别
Person.prototype.name = 'hello';
function Person(){
// 系统自动执行 var this = {_proto_ : Person.prototype}
}
var person = new Person();
//两种修改方式
// 1. Person.prototype.name = 'wow';
// 2. Person.prototype = {
// name : 'wow'
// }
-
成功修改 相当于直接改了空间内的数据
-
Person.prototype.name 还是 hello
这波啊这波是 创建新空间 注意构造函数中的注释 引用的是_proto_ 的指向
方便理解:
var obj = {
name : 'a'};
var obj1 = obj ;
obj = {
name : 'b'}; // obj1 指向的还是a
Person.prototype = {
name : 'a'};
_proto_ = Person.prototype;
Person.prototype = {
name : 'b'};
换了个空间
1改房间中属性
2直接换房间
注意刚才的顺序!!
Person.prototype.name = 'hello';
function Person(){
// 系统自动执行 var this = {_proto_ : Person.prototype}
}
Person.prototype = {
name : 'wow'
}
var person = new Person();
现在成功修改 new在后面
原型链
原型链构成就不用我多说了吧
增删改查
同上面原型
this 小知识
Son.prototype = {
name : 'niko',
sayName : function (){
console.log(this.name);
}
}
function Son () {
this.name = 'dio';
}
var son = new Son(); // dio
this 指向调用方法的人 此处是 son 调用
Object.create(原型)
更方便的构建
var obj = {
name : 'sunny' , age : 123};
var obj1 = Object.create(obj); // obj1 原型就是obj 可以使用name和age
等同于
Obj.prototype.name = 'sunny';
function Obj() {
}
var obj1 = new Obj();
//var obj1 = Object.creat(Obj.prototype); 和上面相等 构造函数是空的就一样
绝大多数 对象最终端都是 Object.prototype
原型链终端 Object.prototype
里面有toString 等方法 (包装类也有自己的toString)
注意绝大多数,有特例,用Object.creat() 构造时
原型可以是 null
var obj = Object.creat(null);
就没有Object.prototype 中的属性方法了
设置为null之后 人为的添加 _proto_
无法使用
(睡前疑问) _proto_
和 .prototype
toString 重写
123.toString
报错 点识别成浮点型数字 得赋值给变量 借助中间量调用
123的toString不是Object的 是 Number自己的方法
var num = 123;
num.toString(); --> // new Number(num).toString();
Number.prototype.toString = function(){
} --> 有自己的toString
Number.prototype._proto_=Object.prototype
这种情况叫 方法重写
: 同名方法实现不同功能 z
在原型链 前端 覆盖
调用 document.write(xx); 时 调用toSting(); 方法
题外话 精度
js可正常计算的范围 小数点前16位 后16位
call / apply
作用 改变 this 指向
目的是 把执行函数里的this改变成传入的对象
区别 传参列表不同
var name = "1";
var obj = {
name:2,
prop: {
name:3,
getName: function() {
return this.name;
}
}
}
console.log(obj.prop.getName()); //3
console.log(obj.prop.getName.call(obj)); //2
console.log(obj.prop.getName.call(this)); //1 在全局的this 是window
如果想得到3 直接 obj.prop.getName() 即可,这事方法的当前对象是prop
如果想得到2 我们可以 obj.prop.getName.call(obj) 就是把obj对象传到方法内,这时候的this对象是obj, this.name 等同于obj.name
1也是同理 obj.prop.getName.call(this) 这里的this是当前页面 传window也是一样的
当然也可以使用apply, apply 和 call 的不同在于call,就是call方法接受的是若干个参数的列表,而apply方法接受的是一个包含多个参数的数组。 apply(thisargs,[])用数组给方法传递参数, call(this, param1,param2); 下面一个小例子
function callTest(name, price) {
console.info(name + "-" + price);
}
callTest.call(this, 'superbing', 100);
callTest.apply(this, ['superbing', 200]);
实用示例
借用别人的函数实现自己的功能
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex; // Person的this
}
function Student(name,age,sex,tel,grade){
// var this ={} 等待赋值
Person.call(this,name,age,sex);
this.tel = tel;
this.grade = grade;
}
var student = new Student('sunny',123,'male',139,2017);
把Student对象传到Person里 使Person中的this实际上指的是Student中的变量
相当于把Person的三句拿到Student里了
别人的构造完全符合自己的时候简写
prototype 和 proto
这个不错