[渡一] 171111 原型链、方法重写、call&apply
来源:互联网 发布:sql安装提示之前挂起 编辑:程序博客网 时间:2024/05/22 14:20
tips1.原型链
//一个原型(本身是一个对象)中有两个属性:constructor & __proto__GrandFather.prototype.lastName = 'deng';function GrandFather() { this.bike = 1;}Father.prototype = new GrandFather();function Father() { this.fortune = { money: 9999999, house: 4 } this.name = "hahah" this.girl = 'h1' }Son.prototype = new Father(); //更改了原型function Son() { this.name = 'heihei' this.age = 20;}var oSon = new Son();oSon.lastName = 'Chen'; // GrandFather.prototype.lastName = 'hong';var oSon2 = new Son();console.log(oSon2.lastName);oSon.__proto__.fortune.house += 1; // Son.prototype.fortune.house += 1;// Son.prototype.fortune.house += 1;var oSon2 = new Son();console.log(oSon2.fortune.house);console.log(oSon.fortune.money);oSon.girl = 'h2';console.log(oSon.girl);console.log(oSon2.girl);// oSon.lastName = {// name: 'chen'// }console.log(oSon.lastName);console.log(oSon2.lastName);oSon.fortune = { money: 8888888, house: 3} // oSon.__proto__.fortune// Son.prototype.fortune = {// money: 8888888,// house: 3//}// Son.prototype = {// name: 'hehe',// fortune: {// money: 7777777,// house: 2// }// } var oSon3 = new Son();console.log(oSon.fortune.house); //3console.log(oSon3.fortune.house); //5console.log(oSon2.fortune.house); //5
- 改变默认原型对象
- oSon.lastname = ‘cherry’ | Oson.fortune = { house = 3} 这些是在oSon对象里添加了新的属性,该行为只与自身有关
- oSon.fortune.house = ‘4’ 是改变了原型的某一项属性,凡是指向该原型对象,均受影响
- Son.prototype = {fortune: { house: 2 }} 是更改了原型的指向,在更改前的对象的_proto_指向不变,新建的对象会按照新的原型继承
- 原型链的顶端都是Object.prototype -> {} | var obj = Object.create(demo) [括号里传参数null(没有原型)或者object(指定原型)] / [obj._proto_== demo]
tips2.原型方法的重写
GrandFather.prototype.lastName = 'deng';GrandFather.prototype.say = function() { console.log('tell me GrandFather');};function GrandFather() { this.bike = 1;}Father.prototype = new GrandFather();function Father() { this.fortune = { money: 9999999, house: 4 } this.name = "hahah" this.girl = 'h1' this.say = function() { console.log('tell me father'); }}Son.prototype = new Father(); function Son() { this.name = 'heihei' this.age = 20;}var oSon = new Son();oSon.say();
- 对象通过原型链从下游向上游寻找目标,若顶端有目标,中间有目标,则使用中间的目标,中间的目标覆盖上游目标。
Object.prototype.toString(); //谁调用了这个方法,调用方法的类型就可以输出var obj = {};obj.toString(); //[object Object]var arr = [1, 2, 3];arr.toString(); //1,2,3 用toString没有实现功能//arr.constructor(查询构造函数) -> function Array(){[native code]}//Array.prototype -> toString 方法在下游被重写
- 原本在原型链顶端的Object.prototype中有目标方法toString();但在搜索过程中下游Array.prototype中重新定义了toString();导致无法实现预想功能
console.log(Object.prototype.toString.call(arr));
- 使用call来改变this的指向,即‘arr’使用‘Object.prototype.toString’方法而不是默认的‘Array.prototype.toString’
tips3.call&apply
每个函数都包含两个非继承而来的方法:call()方法和apply()方法。
都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。
一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。
相同点:这两个方法的作用是一样的。
不同点:接收参数的方式不同。
apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
语法:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。
说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个 TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。
语法:call([thisObject[,arg1 [,arg2 [,…,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。
说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。
后面使用前面的功能,后面替换前面的对象
function Person(name, age) { //(Person)var this = { //name:null, //age:null, --------------?? //} this.name = name; this.age = age;}function Student(name, age, myClass) { //构造函数,(Student)var this = { //myClass:null, //name: //age: //} Person.call(this, name, age); //Person.name -> Student.name this.myClass = myClass;}console.log(new Student('cst', 20, 1));
- (student)替换了(person)的this,相当于student使用了person的方法
var numObj = { x: 1, y: 2}function add(a, b) { console.log(this.x + a + this.y + b);}add(3, 4); //NaN undefined+3+undefined+4//window.add.call(window) this->window window里没有x,y// add.call(numObj, 3, 4); //10add.apply(numObj, [3, 4]);
- numObj使用了add中的方法,numObj把自己的属性代入进去
function cat() {} cat.prototype = { food: "fish", say: function() { alert("I love " + this.food); } } var blackCat = new cat; blackCat.say(); var whiteDog = { food: 'bone', }blackCat.say.call(whiteDog);//动态改变this,当一个对象没有某个方法,但是其他的有
- whiteDog使用blackCat的方法,并带着自己的参数‘bone’
window.color = 'red';document.color = 'yellow';var s1 = { color: 'blue'};function changeColor() { console.log(this.color);}changeColor.call(); //red (默认传递参数)changeColor.call(window); //redchangeColor.call(document); //yellowchangeColor.call(this); //red -------------------??changeColor.call(s1); //blue
var Pet = { words: '...', speak: function(say) { console.log(say + this.words) }}Pet.speak('Speak'); // 结果:Speak...var Dog = { words: 'Wang'}//将this的指向改变成了DogPet.speak.call(Dog, 'Speak'); //结果: SpeakWang
- Dog使用Pet的方法
[1127追加]:
tip1:探索普通函数和构造函数内部区别
function test() { console.log(this); console.log('test');}test();//'this'是 window.this 即函数内部没有创建this对象//普通函数执行功能
function Test() {//var this = {__proto__:test.prototype}console.log(this);console.log('test');//return this}var a = new Test();//通过new定义函数,是构造函数,通常每个单词首字母大写//通过new来执行函数,会在函数中默认定义一个this对象,会返回一个对象//运行结果可以看出'this'并没有输出,是函数内部的this对象
function test() {console.log(this);console.log('test');}test();test.call(window);var obj = {name: 'cst'}test.call(obj);//执行test 相当于test.call(window) 'window' call 'test' //括号内第一个参数就决定了前面这个函数中this是谁//不传参数默认为test.call(window)//传入参数'obj' 'obj' call 'test' =>(this->obj)=>console.log(obj)
function Person(name, age, sex) {//预编译阶段构造函数 creative new this {}//预编译后产生this对象,每次执行都新建一个对象,都不是一个this this.name = name; this.age = age; this.sex = sex;}var oPerson = new Person(); //构造函数的方式运行函数,会创建this对象,执行时this才有意义function Student(name, age, sex, grade, clas) {// creative this {} // this.name = name;// this.age = age;// this.sex = sex;Person.call(this, name, age, sex); //不传参数默认是window 在此处传实参this.grade = grade;this.clas = clas;//return this;}var oStudent = new Student('yp', 18, 'man', 3, 3);
阅读全文
0 0
- [渡一] 171111 原型链、方法重写、call&apply
- javascript原型+call/apply
- call apply方法
- call和apply方法
- call 和 apply 方法
- Js apply call方法
- call apply方法
- call()和apply()方法
- JS-call/apply 方法
- apply()和call()方法
- js中函数对象的方法,原型方法apply、call、bind、toString、toLocaleString、valueOf
- JavaScript call、apply、bind、对象原型
- JavaScript原型、函数伪装(apply,call)、继承
- apply()方法和call()方法
- #笔记#圣思园 JavaWeb 第57讲——JS继承:对象冒充、call方法、apply方法、原型链方式、混合方式
- javascript中的apply&call方法
- javascript call和apply方法
- javascript call和apply方法
- git使用
- netty中的ChannelHandler
- Uva1151.Buy or Build (最小生成树)
- java生成验证码
- ajax
- [渡一] 171111 原型链、方法重写、call&apply
- 如何在centos6下安装gcc
- mysq易错知识总结
- NOIp2017 帅记
- 学习笔记系列之Redis | 第一章 Redis简介与环境搭建
- 获取a标签的父元素
- 图形用户界面
- java操作hdfs,实现文件上传、下载以及查看当前文件夹下所有文件
- 编程之路小目标