求一个字符串的字节长度

注意点:汉字的字节长度是两个

// 求一个字符串字节长度(汉字是两个字节)
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
复制代码

原因(对象空间的引用或者指向)

  1. person.name -> this.proto(Person.prototype原型)上的name属性
  2. Person.prototype -> 一个对象空间 -> {name:"sunny"}
  3. person.name -> this.proto -> 一个对象空间 -> {name:"sunny"}
  4. 修改指向引用 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指向 区别: 后面传的参数形式不同

  1. 改变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指向 借用方法复制代码
  1. 改变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}
复制代码
  1. call/apply传参形式不同 Person.apply(obj, ["cheng",300]) Person.call(this, [name, age, sex]);

继承那点方式

  1. 传统的形式-> 原型链

    过多的继承了没有用的属性

    // 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); // 动物
    复制代码
  2. 借用构造函数(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();
    复制代码
  3. 共享原型(多个构造函数共用一个原型)

    一个原型修改另一个也在修改

    // 标准方法
    function inherit(Target, Origin) {Target.prototype = Origin.prototype;
    }
    复制代码
  4. 圣杯模式(完善)

    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;}
    }())
    复制代码
  5. 深拷贝继续(数组和对象)

    function deepCopy(p, c) {
    &emsp;&emsp;&emsp;var c = c || {};
    &emsp;&emsp;&emsp;for (var i in p) {
    &emsp;&emsp;&emsp;&emsp;&emsp;if (typeof p[i] === 'object') {
    &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;c[i] = (p[i].constructor === Array) ? [] : {};
    &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;deepCopy(p[i], c[i]);
    &emsp;&emsp;&emsp;&emsp;&emsp;} else {
    &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;c[i] = p[i];
    &emsp;&emsp;&emsp;&emsp;&emsp;}
    &emsp;&emsp;&emsp;}
    &emsp;&emsp;&emsp;return c;
    }
    复制代码

转载于:https://juejin.im/post/5a6d7a86f265da3e4b770524

JavaScript系列-(原型-原型连-call-apply-继承)相关推荐

  1. (四)我的JavaScript系列:原型链

    夜深风竹敲秋韵,万叶千声皆是恨. 原型链对于JavaScript来说是个很核心的概念.JavaScript不是基于类模板的面向对象语言:反而,它的面向对象机制是基于原型的.我们不可能说某个对象属于什么 ...

  2. 深入理解JavaScript系列(5):强大的原型和原型链

    前言 JavaScript 不包含传统的类继承模型,而是使用 prototypal 原型模型. 虽然这经常被当作是 JavaScript 的缺点被提及,其实基于原型的继承模型比传统的类继承还要强大.实 ...

  3. 对Javascript 类、原型链、继承的理解

    一.序言   和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...

  4. JavaScript中的原型(prototype)与继承

    在JavaScript中,原型是用来模仿其他「类」语言继承机制的基础.原型并不复杂,原型只是一个对象. 一.原型对象 1.1 什么是原型对象 每当我们创建了一个函数后,这个函数就拥有了一个protot ...

  5. 理解JavaScript中的原型继承(2)

    两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...

  6. JavaScript中的原型继承原理

    在JavaScript当中,对象A如果要继承对象B的属性和方法,那么只要将对象B放到对象A的原型链上即可.而某个对象的原型链,就是由该对象开始,通过__proto__属性连接起来的一串对象.__pro ...

  7. JavaScript中的原型和继承

    请在此暂时忘记之前学到的面向对象的一切知识.这里只需要考虑赛车的情况.是的,就是赛车. 最近我正在观看 24 Hours of Le Mans ,这是法国流行的一项赛事.最快的车被称为 Le Mans ...

  8. 在JavaScript实现基于原型的继承

    5年前我写了在JavaScript中实现基于类模式的继承.它显示了JavaScript是基于像类一样,原型的语言(class-free, prototypal).并且它有足够的能力去模仿一个" ...

  9. JavaScript 设计模式学习第五篇-继承与原型链

    JavaScript 是一种灵活的语言,兼容并包含面向对象风格.函数式风格等编程风格.我们知道面向对象风格有三大特性和六大原则,三大特性是封装.继承.多态,六大原则是单一职责原则(SRP).开放封闭原 ...

  10. JavaScript学习(五十二)—继承、call方法和apply方法

    JavaScript学习(五十二)-继承.call方法和apply方法 学习内容 一.继承 二.call方法 三.apply方法 一.继承 所谓继承就是两个构造方法建立起来的某种联系,通过某种联系,可 ...

最新文章

  1. 使用 Code Snippet 简化 Coding
  2. 刚入Linux坑常见的8大问题
  3. python leetcode_leetcode 介绍和 python 数据结构与算法学习资料
  4. 鸿蒙系统怎么换windows,求助~鸿蒙系统windows环境搭建(hpm-cli安装失败)!
  5. GTimeSheet正式启用官方网站
  6. line java_java – Line Rasterization / 4-bresenham
  7. python输入变量输出常量_Python输入input、输出print
  8. 对计算机专业的认识500字_【热门】我的朋友作文500字4篇
  9. 4. tensorflow2实现抽样分布—卡方分布、F分布、t分布、Beta分布、Gamma分布——python实战
  10. 处理顶点——自动计算顶点缓冲中所有顶点的法线
  11. 国科大学习资料--自然语言处理(宗成庆)-2019期末考试题
  12. Matlab根据滤波器系数画出幅频特性曲线
  13. Vimac 0.3.14最新版 (一款让你用键盘代替鼠标软件)
  14. js 计算两个时间的时间差
  15. 配流06—frank_wolfe配流算法
  16. 由一次不断GC并耗费过长的时间所想到的工具 - jvmkill与jvmquake
  17. 2021年中国冰雪旅游行业市场现状分析,“三足鼎立、两带崛起、全面开花”新格局形成「图」
  18. 扭蛋机(bilibili)
  19. C语言基础 输出月份名 问题
  20. PRESTO SQL总结分享

热门文章

  1. startupinfo为什么需要初始化_为什么 TCP 建立连接要三次握手
  2. px4驱动linux,px4开发指南——linux下qgroundcontrol地面站安装
  3. 小波包分解 matlab_多尺度一维小波分解
  4. django html5 video,Django Web中的静态文件之HTML5第1篇
  5. python tab键自动补全_Python Tab自动补全
  6. 如何将模糊的图片变得清晰
  7. VisionSeed 腾讯优图实验室
  8. 向量、矩阵的范数--Lp定义
  9. matlab 投票法_SVM算法原理及其Matlab应用
  10. c++气泡框提示_黄骅屋顶隔热气泡膜厂家,机房专用吸音板_德发防火保温建材