JavaScript系列-(原型-原型连-call-apply-继承)
求一个字符串的字节长度
注意点:汉字的字节长度是两个
// 求一个字符串字节长度(汉字是两个字节)
function bytesLength(str) {var count = 0;for(var i=0; i<str.length;i++) {if(str.charCodeAt(i) > 255) {count += 2;}else {count ++;}}return count;
}
复制代码
原型
定义: 原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象可以继承该原型的属性和方法 (原型也是对象)
可以利用原型的特点和概念,可以提取共有属性
proto&构造函数&new(object)
//Person的对象-原型对象
Person.prototype.name = "abc";
//构造函数 Person
function Person() {// var this = {// _proto_: Person.prototype //}
}
var person = new Person();
复制代码
在new person时 发生:
this -> _proto:Person.prototype()-原型对象 可以person可以调用原型中的属性和方法 person.proto = obj(可以被修改-之后就会继承obj的内容)
插入一个小问题:代码
Person.prototype.name = "sunny";
function Person() {// var this = {// _proto_: Person.prototype //}
}
var person = new Person();Person.prototype = {name:"cherry"
}
console.log(person.name) // sunny
复制代码
原因(对象空间的引用或者指向)
- person.name -> this.proto(Person.prototype原型)上的name属性
- Person.prototype -> 一个对象空间 -> {name:"sunny"}
- person.name -> this.proto -> 一个对象空间 -> {name:"sunny"}
- 修改指向引用 Person.prototype -> 一个对象空间 -> {name:"cherry"} 5.由于person.name 先new -> this.proto -> 的指向空间没有变 -> {name:'sunny'} 所以:person.name = 'sunny'
如果纯粹修改Person.prototype.name = "cherry"; 则person.name = 'cherry'
原型连
概念:new对象沿着作用域链去查找属性和方法的 链 引出:
// 如果要求打印出son.lastName
son this._porto_: Son.prototypefather this._porto_: Father.prototypegrand this._porto_: Object由于 son this._porto_ -> father this._porto_ -> father grand._porto_ -> {lastName,Object.prototype} 所以son.lastName 顺这链找到了grand.lastName = "Deng"console.log(son.lastName) // "Deng"
复制代码
Object.create()
创建对象 Object.create(原型) 创建对象、指定原型
var obj = { name:'sunny'}
var obj1 = Object.create(obj)// obj1 = {} 并且obj1的原型是obj obj1.name= "sunny"
复制代码
不是所有对象都是继承自Object Object.create(null)是特例
判断类型
Object.prototype.toString.call(123)
"[object Number]"
复制代码
call/apply
作用: 改变this指向 区别: 后面传的参数形式不同
- 改变this指向1
function Person(name, age) {// Person.call() 会将this -> objthis.name = name;this.age = age;
}var person = new Person("deng", 100)
var obj = {};
Person.call(obj, "cheng",300) //改变this指向 借用方法复制代码
- 改变this指向2
function Person(name, age, sex) {this.name = name;this.age = age;this.sex = sex;
}function Student(name, age, sex, tel, grade) {// var this = StudentPerson.call(this, name, age, sex); //Student则有了Person的属性this.tel = tel;this.grade = grade;
}var student = new Student('sunny',123,'male',139,2017)student -> {name: "sunny", age: 123, sex: "male", tel: 139, grade: 2017}
复制代码
- call/apply传参形式不同 Person.apply(obj, ["cheng",300]) Person.call(this, [name, age, sex]);
继承那点方式
传统的形式-> 原型链
过多的继承了没有用的属性
// Animal构造函数 function Animal(){ } // Animal原型山添加一个属性species Animal.prototype.species = "动物";// 将Cat的prototype对象指向Animal的prototype对象 Cat.prototype = Animal.prototype;// 原型的修改会导致Cat的构造器的修改,所以需要将cat的构造器重新指向Cat它自己 function Cat(){ } Cat.prototype.constructor = Cat; var cat1 = new Cat("大毛","黄色"); // cat的对象中就有了species这个属性 alert(cat1.species); // 动物 复制代码
借用构造函数(call/apply)
不能继承借用构造函数的原型 每次构造函数都要多走apply/call函数
function Person(name, age, sex) {this.name = name;this.age = age;this.sex = sex; }function Student(name, age, sex, tel, grade) {// var this = StudentPerson.call(this, name, age, sex); //Student则有了Person的属性 用apply也行this.tel = tel;this.grade = grade; } var student = new Student(); 复制代码
共享原型(多个构造函数共用一个原型)
一个原型修改另一个也在修改
// 标准方法 function inherit(Target, Origin) {Target.prototype = Origin.prototype; } 复制代码
圣杯模式(完善)
function Father() {} function Son() {}function F() {} // 中间层 F.prototype = Father.prototype;// son就形成了继承 Son.prototype = new F();//如果一个修改这样不会影响另一个(因为new F是独立存在的一个空间) 复制代码
标准方法:
function inherit(Target, Origin) {function F() {};F.prototype = Origin.prototype;Target.prototype = new F();// 构造器重新修改过来Target.prototype.constructor = Target;// 继承自谁(保存值)Target.uber = Origin.prototype; } 复制代码
高级写法(一般是库写法)
私有化属性(形成了闭包,变量引用与保留了inherit() 上下文)
var inherit = (function () {var F = function() {}return function (Target, Origin) {F.prototype = Origin.prototype;Target.prototype = new F();// 构造器重新修改过来Target.prototype.constructor = Target;// 继承自谁(保存值)Target.uber = Origin.prototype;} }()) 复制代码
深拷贝继续(数组和对象)
function deepCopy(p, c) {    var c = c || {};    for (var i in p) {      if (typeof p[i] === 'object') {        c[i] = (p[i].constructor === Array) ? [] : {};        deepCopy(p[i], c[i]);      } else {         c[i] = p[i];      }    }    return c; } 复制代码
转载于:https://juejin.im/post/5a6d7a86f265da3e4b770524
JavaScript系列-(原型-原型连-call-apply-继承)相关推荐
- (四)我的JavaScript系列:原型链
夜深风竹敲秋韵,万叶千声皆是恨. 原型链对于JavaScript来说是个很核心的概念.JavaScript不是基于类模板的面向对象语言:反而,它的面向对象机制是基于原型的.我们不可能说某个对象属于什么 ...
- 深入理解JavaScript系列(5):强大的原型和原型链
前言 JavaScript 不包含传统的类继承模型,而是使用 prototypal 原型模型. 虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大.实 ...
- 对Javascript 类、原型链、继承的理解
一.序言 和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...
- JavaScript中的原型(prototype)与继承
在JavaScript中,原型是用来模仿其他「类」语言继承机制的基础.原型并不复杂,原型只是一个对象. 一.原型对象 1.1 什么是原型对象 每当我们创建了一个函数后,这个函数就拥有了一个protot ...
- 理解JavaScript中的原型继承(2)
两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...
- JavaScript中的原型继承原理
在JavaScript当中,对象A如果要继承对象B的属性和方法,那么只要将对象B放到对象A的原型链上即可.而某个对象的原型链,就是由该对象开始,通过__proto__属性连接起来的一串对象.__pro ...
- JavaScript中的原型和继承
请在此暂时忘记之前学到的面向对象的一切知识.这里只需要考虑赛车的情况.是的,就是赛车. 最近我正在观看 24 Hours of Le Mans ,这是法国流行的一项赛事.最快的车被称为 Le Mans ...
- 在JavaScript实现基于原型的继承
5年前我写了在JavaScript中实现基于类模式的继承.它显示了JavaScript是基于像类一样,原型的语言(class-free, prototypal).并且它有足够的能力去模仿一个" ...
- JavaScript 设计模式学习第五篇-继承与原型链
JavaScript 是一种灵活的语言,兼容并包含面向对象风格.函数式风格等编程风格.我们知道面向对象风格有三大特性和六大原则,三大特性是封装.继承.多态,六大原则是单一职责原则(SRP).开放封闭原 ...
- JavaScript学习(五十二)—继承、call方法和apply方法
JavaScript学习(五十二)-继承.call方法和apply方法 学习内容 一.继承 二.call方法 三.apply方法 一.继承 所谓继承就是两个构造方法建立起来的某种联系,通过某种联系,可 ...
最新文章
- 使用 Code Snippet 简化 Coding
- 刚入Linux坑常见的8大问题
- python leetcode_leetcode 介绍和 python 数据结构与算法学习资料
- 鸿蒙系统怎么换windows,求助~鸿蒙系统windows环境搭建(hpm-cli安装失败)!
- GTimeSheet正式启用官方网站
- line java_java – Line Rasterization / 4-bresenham
- python输入变量输出常量_Python输入input、输出print
- 对计算机专业的认识500字_【热门】我的朋友作文500字4篇
- 4. tensorflow2实现抽样分布—卡方分布、F分布、t分布、Beta分布、Gamma分布——python实战
- 处理顶点——自动计算顶点缓冲中所有顶点的法线
- 国科大学习资料--自然语言处理(宗成庆)-2019期末考试题
- Matlab根据滤波器系数画出幅频特性曲线
- Vimac 0.3.14最新版 (一款让你用键盘代替鼠标软件)
- js 计算两个时间的时间差
- 配流06—frank_wolfe配流算法
- 由一次不断GC并耗费过长的时间所想到的工具 - jvmkill与jvmquake
- 2021年中国冰雪旅游行业市场现状分析,“三足鼎立、两带崛起、全面开花”新格局形成「图」
- 扭蛋机(bilibili)
- C语言基础 输出月份名 问题
- PRESTO SQL总结分享
热门文章
- startupinfo为什么需要初始化_为什么 TCP 建立连接要三次握手
- px4驱动linux,px4开发指南——linux下qgroundcontrol地面站安装
- 小波包分解 matlab_多尺度一维小波分解
- django html5 video,Django Web中的静态文件之HTML5第1篇
- python tab键自动补全_Python Tab自动补全
- 如何将模糊的图片变得清晰
- VisionSeed 腾讯优图实验室
- 向量、矩阵的范数--Lp定义
- matlab 投票法_SVM算法原理及其Matlab应用
- c++气泡框提示_黄骅屋顶隔热气泡膜厂家,机房专用吸音板_德发防火保温建材