9159金沙游艺场

图片 12
有趣的CSS题目(6): 全兼容的多列均匀布局问题

c#调用腾讯云API的实例

理解JavaScript的原型属性

关于作者:alvendarthy

图片 1

一个热爱生活的家伙!
个人主页 ·
我的文章 ·
16

图片 2

2. JavaScript 实现继承的语言特性

  • 当尝试访问 JavaScript
    对象中不存在的属性时,解析器会查找匹配的对象原型。例如调用
    car.toString(),如果 car 没有 toString 方法,就会调用 car
    对象的原型。 这个查找过程会一直递归,
    直到查找到匹配的原型或者继承链尽头。

  • 调用  new Car()
    会创建一个新的对象,并初始化为 Car.prototype。
    这样就允许为新对象设置原型链。需要注意的是,new Car() 只有当  Car 是函数时才有意义。
    此类函数即所谓构造函数

  • 调用对象的一个成员函数时, this
    的值被绑定为当前对象。例如调用 “abc”.toString(),this 的值被设置为
    “abc”,然后调用 toString 函数。该技术支持代码重用:同样的代码,可在
    this
    为各种不同的值时调用。对象的成员函数,也被称为对象的方法。

   图片 3

  首先,我们定义构造函数 Rectangle。
按照规范,我们大写构造函数名首字母,表明它可以用 new
调用,以示与其他常规函数的区别。构造函数自动将 this
赋值为一空对象,然后代码中用 x 和 y 属性填充它,以备后用。然后,
Rectangle.prototype 新增一个通过 x 和 y 属性计算周长成员函数。 注意 this
的使用,在不同的对象中,this
会有不同的值,这些代码都可以正常工作。最后, 一个名为 rect
的对象创建出来了。 它继承了 Rectangle.prototype, 我们可以调用
rect.perimeter(), 然后将结果打印到控制台。

简单的方法

JavaScript 实现继承的语言特性

以下语言特性共同实现了 JavaScript 继承。

  • 当尝试访问 JavaScript
    对象中不存在的属性时,解析器会查找匹配的对象原型。例如调用 car.toString(),如果
    car 没有 toString 方法,就会调用 car 对象的原型。
    这个查找过程会一直递归, 直到查找到匹配的原型或者继承链尽头。
  • 调用  new Car() 会创建一个新的对象,并初始化为 Car.prototype
    这样就允许为新对象设置原型链。需要注意的是,new Car()
    只有当  Car 是函数时才有意义。 此类函数即所谓构造函数。
  • 调用对象的一个成员函数时, this
    的值被绑定为当前对象。例如调用 "abc".toString()this
    的值被设置为 "abc",然后调用 toString
    函数。该技术支持代码重用:同样的代码,可在 this
    为各种不同的值时调用。对象的成员函数,也被称为对象的方法。

1.原型继承

  面向对象编程可以通过很多途径实现。其他的语言,比如
Java,使用基于类的模型实现: 类及对象实例区别对待。但在 JavaScript
中没有类的概念,取而代之的是一切皆对象。JavaScript
中的继承通过原型继承实现:一个对象直接从另一对象继承。对象中包含其继承体系中祖先的引用——对象的
prototype 属性。

// out:  100

举个栗子

我们用面向对象编程,实现一个计算矩形周长的例子。

JavaScript

function Rectangle(x, y) { this.x = x; this.y = y; }
Rectangle.prototype.perimeter = function() { return 2 * (this.x +
this.y); } var rect = new Rectangle(1, 2);
console.log(rect.perimeter()); // outputs ‘6’

1
2
3
4
5
6
7
8
9
10
11
function Rectangle(x, y) {
    this.x = x;
    this.y = y;
}
 
Rectangle.prototype.perimeter = function() {
    return 2 * (this.x + this.y);
}
 
var rect = new Rectangle(1, 2);
console.log(rect.perimeter()); // outputs ‘6’

首先,我们定义构造函数 Rectangle
按照规范,我们大写构造函数名首字母,表明它可以用 new
调用,以示与其他常规函数的区别。构造函数自动将 this
赋值为一空对象,然后代码中用 xy 属性填充它,以备后用。

然后, Rectangle.prototype 新增一个通过 xy
属性计算周长成员函数。 注意 this 的使用,在不同的对象中,this
会有不同的值,这些代码都可以正常工作。

最后, 一个名为 rect 的对象创建出来了。
它继承了 Rectangle.prototype, 我们可以调用 rect.perimeter()
然后将结果打印到控制台。

prototype 属性名称带来的误解

  有一些关于 JavaScript 的原型的误解。
一个对象的原型与对象的 prototype 属性并非一回事。
前者用于在原型链中匹配不存在的属性。后者用于通过 new
关键字创建对象,它将作为新创建对象的原型。
理解二者的差异,将帮助你彻底理解 JavaScript 中的原型特性。

  Rectangle.prototype 是用 new
Rectangle() 创建出来对象的原型, 而 Rectangle 的原型实际上是 JavaScript
的 Function.prototype。(子对象的原型是父对象的 prototype 属性
对象中保存原型的变量,也被称之为内部原型引用(the internal prototype
link),历史上也曾称之为 __proto__ ,对这个称谓始终存在一些争议。
更精确的,它可以被称为 Object.getPrototypeOf(…) 的返回值。

var obj = new Object();

prototype 属性名称带来的误解

有一些关于 JavaScript 的原型的误解。
一个对象的原型与对象的 prototype 属性并非一回事。
前者用于在原型链中匹配不存在的属性。后者用于通过 new
关键字创建对象,它将作为新创建对象的原型。
理解二者的差异,将帮助你彻底理解 JavaScript 中的原型特性。

在我们的例子中, Rectangle.prototype 是用 new Rectangle()
创建出来对象的原型, 而 Rectangle 的原型实际上是 JavaScript
的 Function.prototype。(子对象的原型是父对象的 prototype 属性)

对象中保存原型的变量,也被称之为内部原型引用(the internal prototype
link
),历史上也曾称之为 __proto__ ,对这个称谓始终存在一些争议。
更精确的,它可以被称为 Object.getPrototypeOf(...) 的返回值。

2 赞 5 收藏 2
评论

因为我还是不准备使用这个方法, 所以这里还是不加描述了.

理解JavaScript的原型属性

2016/06/21 · JavaScript
· 2 评论 ·
原型

本文由 伯乐在线 –
alvendarthy
翻译,sunshinebuel
校稿。未经许可,禁止转载!
英文出处:bytearcher。欢迎加入翻译组。

理解 JavaScript
prototype属性不太容易。你也许知道它同面向对象编程(OOP)和对象继承有关,但未必对其技术原理非常清楚。

上面的Rectange类, 可以改为下面的方式实现.

原型继承

面向对象编程可以通过很多途径实现。其他的语言,比如
Java,使用基于类的模型实现: 类及对象实例区别对待。但在 JavaScript
中没有类的概念,取而代之的是一切皆对象。JavaScript
中的继承通过原型继承实现:一个对象直接从另一对象继承。对象中包含其继承体系中祖先的引用——对象的 prototype 属性。

class 关键字是在 ES6 中首次引入 JavaScript
的。其实,它并没有为面向对象继承引入新模型, class
关键字通过语法糖,实现了本文介绍的原型特性和构造函数。

 

 

 

  return x * y;

console.log(“3” * 4);

  var count = base;

这种继承方式和class-based的继承不一样,
直接使用了javascript的prototype特性, 在真正的class没有出来之前,
我个人对这样的方式好感更多. 主要可以参考的还是Douglas Crockford的文章,
见Prototypal Inheritance in JavaScript

                var rect = {};

闭包

正因为其实对象就是一个关联数组, 所以同样可以用for in来遍历,
作用就像是python中的dir一样. 类似这种自审视的功能,
在传统静态语言是较为稀缺的, 在那种语言里这种功能叫做反射.
相配套的还有typeof操作符, hasOwnProperty, propertyIsEnumerable,
isPrototypeof函数.

有些不一样的是, 因为javascript中函数是第一类值,
所以可以很自然的在这个对象中添加函数, 完成完整的数据封装.
用{}来初始化上述对象的话, 会更加简单:

function Rectangle(w, h) {

类属性(Class Properties)

obj2(2);

本质上是因为一旦函数调用参数不够时, 后面的参数都会被置为undefined.
所以虽然javascript不支持默认参数, 但是可以模拟出来.

obj1 = makeIncrementor(10);

 

 

mul(10);

 

  var height = h;

                var height = h;   // private

console.log( a.sort( function(a, b) { return a – b; } ) );

var Rectangle = { 

   createNew: function(w, h) {

var sub = function(x, y) {

}

  }

obj.hello();

 

上面的例子较好的展示了闭包的特性, 可以获得上层函数的参数和变量,
并且各自互相独立, 因为闭包对局部状态的保存,
很多时候能当作一个对象来使用.

函数级作用域

}

 

                rect.area = function() { return width * height; };

}

Rectangle.prototype.area = function() {  return this.width *
this.height; };

 console.log(rect.area());

                return rect;

function add(x, y) {

 

               return rect;

 

自定义对象:

上述的代码在现在已经不稀奇了,
但是相对C++来说还是更先进的.(可见C++多落后了)

 

    for (var i = 0, j = arguments.length; i < j; i++) {

// out: 12

 

 

 var rect = Rectangle.createNew(2, 3);

  else {

    console.log(“hello,” + this.name);

其实也不是完全没有用过javascript,
以前在开发一个Unity项目的时候用过一下Unity里面的javascript,
只不过那个javascript我甚至都只能称之为UnityScript.
太多太多自己实现的特性, 而又有些不够完整. 现在,
认识一下真正的javascript吧.

                rect.area = function() { return this.width *
this.height; };

 

 

function mul(x, y) {

 

JavaScript本身就是设计为一个前端语言, 据说设计只用了10天, 有些缺陷,
但是的确足够简单. 虽然JavaScript The Definitive
Guide和大多数的语言书籍一样厚如砖头,
但是其实语言本身的介绍只有前面近200页,
这个厚度其实也就和R&D中描述的C语言差不多.

  return x + y;

console.log(“3” * “4”);

 

简单的说就是子类讲自己的prototype变量设为想要继承的父类对象,
根据javascript的特性, 当一个函数找不到时, 会在prototype中寻找,
也就相当于子类没有重载时直接使用父类的函数. 当一个函数可以找到时,
会直接使用子类的函数, 这相当于子类重载了父类的相关函数.

Rectangle.UNIT = new Rectangle(1, 1);

 

console.log(rect1.are());

javascript算是第一个让大家知道这个世界上除了从C++一派来的class-based(模版式)的类定义方式,
还有类似self语言的prototype(原型)方式的流行语言.
虽然lua也是prototype方式, 但是毕竟只在游戏圈子里面流行.

              }

                return rect;

字符串为不可变类型, 任何的改变处理都是生成新字符串. 比较时为值比较.
字符串的值比较我个人认为时更加自然的做法,
比Java那种变态的方式要自然的多. 你几乎要反复的告诉每一个新来的程序员,
字符串的值比较在java中要使用equals函数.

 

 

 

因为是hash表, 所以动态添加内容不在话下.

a[a.length] = 3;

}

 

 Rectangle.UNIT = Rectangle.createNew(1, 1); // class propertie

当javascript 2.0加入了class以后,
可能将来使用javascript就和C++等语言区别不大了. 可能会更像UnityScript.

 

  if (n <= 1) {

该方法我第一次是在阮一峰的网络日志上看到的,
见Javascript定义类(class)的三种方法.

// out: 12

 

  this.height = h;

var rect = SubRectangle.createNew(2, 3);

上述代码在调用时不会发生错误, 而是直接把后面的参数抛弃掉.

console.log(“3” + 4 + 5);

    }

甚至于, 后面的两个参数不够的函数调用, 会返回NaN, 也不会发生错误.

}

 }, 

function Rectangle(w, h) {

 

支持NaN, null, undefined这三种表示类似无意义的量的方式,
有的时候这是混乱的根源. 也许还要再加上Infinity.

 

最近语言学习有些疯狂, 从Ruby到Lisp, 然后是C#, 既然已经疯狂了,
就顺面学习一下javascript吧. 对javascript的印象一直不佳,
从骂脏话最多的使用者, 到使用者平反的世界上最被误解的语言,
从所谓的让人抓狂的特性, 到世界上任何可以用javascript实现的东西,
最终都会被javascript实现, 并且, 这是最后一个实现. 出处太多, 不一一列举,
知者已知, 不知者也没有必要为了这些无聊的言论特意找出处了.

javascript只有函数级别的作用域, 函数外都是全局作用域, 没有块级作用域.
意味着类似for, while, if等块中定义的实际是全局变量.
这个设定在现代语言中是逆天的. 于是, 借助匿名函数,
人们想出了更加诡异的解决方案来模拟块级作用域.

// out: 14

 

  }

  }

 

  if (y === undefined) {

               rect.width = w; 

               rect.area = Rectangle._area; 

基于原型的继承

 

 

}

    var sum = 0;

语法细节

与大部分语言一样, javascript也分为原生类型和引用类型,
其中原生类型在拷贝, 参数传递和比较时时通过值的方式,
而引用类型都是通过引用的方式.

  this.getWidth = function() { return w; }

 

  }

  return this.getWidth() * this.getHeight();

 

 

  this.width = w;

}

  console.log(i);

javascript虽然说语法是类C的, 但是起点是Java,
所以尽管设计的面向对象系统虽然不是传统的模版式的,
但是javascript中的字符串都是对象.

javascript有个奇怪的地方是字符串和数字同时使用时:

                rect.width = w;

字符串

var rect1 = new Rectangle(2, 4);

  return x – y;

var SubRectangle = {

也就是说, 相对一些语言(比如php)会自动的将字符串转为数字来说,
javascript是倾向于将数字转为字符串的. 其实因为这种用法过于灵活,
即使是Ruby和Python这样以灵活著称的语言都是不允许这样的自动类型转换的.

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图