现在的位置: 首页 > 综合 > 正文

JS和jquery的几个令人迷惑的问题之二(语句和对象)

2014年09月14日 ⁄ 综合 ⁄ 共 8494字 ⁄ 字号 评论关闭

1.js语句

1.1.条件语句

switch语句

switch (expression){

  case expression1:

    statements;

     break;

   default:

      statements;

      break;

}

case表达式expression1通常是数字和字符串,但标准运行case表达式也可以是其他类型,在expression和case表达式expression1比较的时候,使用的是恒等号===,所以不会有类型转换。

1.2.跳转语句

break和continue是js里面唯一可以使用label的语句

break lable1;

continue lable2;

如果我们希望break语句跳出非就近的循环体或switch语句时,就用得着这样的标签。

continue也有类似的情况。

2.js对象

2.0.几个词汇解释

2.0.1.

here are some terms we’ll use to distinguish among three broad categories of
JavaScript objects and two types of properties:
• A native object is an object or class of objects defined by the ECMAScript specification.
Arrays, functions, dates, and regular expressions (for example) are native
objects.
• A host object is an object defined by the host environment (such as a web browser)
within which the JavaScript interpreter is embedded. The HTMLElement objects
that represent the structure of a web page in client-side JavaScript are host objects.
Host objects may also be native objects, as when the host environment defines
methods that are normal JavaScript Function objects.
• A user-defined object is any object created by the execution of JavaScript code.
• An own property is a property defined directly on an object.
• An inherited property is a property defined by an object’s prototype object.

2.0.2.property attributes(3个)

property attributes:
• The writable attribute specifies whether the value of the property can be set.
• The enumerable attribute specifies whether the property name is returned by a
for/in loop.
• The configurable attribute specifies whether the property can be deleted and
whether its attributes can be altered.

2.0.3.object attributes(3个)

every object has three associated object attributes:
• An object’s prototype is a reference to another object from which properties are
inherited.
• An object’s class is a string that categorizes the type of an object.
• An object’s extensible flag specifies (in ECMAScript 5) whether new properties may
be added to the object.

2.1.属性的继承

注意这里使用了inherit函数来模拟

> // inherit() returns a newly created object that inherits properties from the
undefined
> // prototype object p. It uses the ECMAScript 5 function Object.create() if
undefined
> // it is defined, and otherwise falls back to an older technique.
undefined
> function inherit(p) {
... if (p == null) throw TypeError(); // p must be a non-null object
... if (Object.create) // If Object.create() is defined...
...   return Object.create(p); // then just use it.
... var t = typeof p; // Otherwise do some more type checking
... if (t !== "object" && t !== "function") throw TypeError();
... function f() {}; // Define a dummy constructor function.
... f.prototype = p; // Set its prototype property to p.
... return new f(); // Use f() to create an "heir" of p.
..}
undefined
> var o = {} // o inherits object methods from Object.prototype
undefined
> o.x = 1; // and has an own property x.
1
> var p = inherit(o); // p inherits properties from o and Object.prototype
undefined
> p.y = 2; // and has an own property y.
2
> var q = inherit(p); // q inherits properties from p, o, and Object.prototype
undefined
> q.z = 3; // and has an own property z.
3
> var s = q.toString(); // toString is inherited from Object.prototype
undefined
> q.x + q.y // => 3: x and y are inherited from o and p
3
> s
'[object Object]'
> q
{ z: 3 }
> o.toString()
'[object Object]'
> o
{ x: 1 }
> p
{ y: 2 }
> o.x=11
11
> o
{ x: 11 }
> q.x
11
> q.x+q.y
13
> q.x=111 <span style="color:#330033;"><span style="background-color: rgb(180, 100, 0);">//注意,这里其实是为q增加了一个新的属性x,他覆盖了原型里面继承来的属性x,所以这里设置了新的值,但是原型里面的x并未改变,o.x仍然是11</span></span> 
111
> o.x
11
> q.x+q.y
113
>

在js中,只有在查询属性时才会体会到继承的存在,而设置属性则和继承无关,这是js的一个重要特性,该特性让程序员可以有选择地覆盖集成的属性。

有一个例外,如果o继承了属性x,继承来的属性x是具有setter方法的accessor属性,那么这时候将调用setter方法而不是给o创建一个属性x。这个setter方法操作只是针对o本身的属性,并不会修改原型链。

2.2.属性访问错误

var empty = {}; // An object with no properties
var point = { x:0, y:0 }; // Two properties
var point2 = { x:point.x, y:point.y+1 }; // More complex values
var book = {
  "main title": "JavaScript", // Property names include spaces,
  'sub-title': "The Definitive Guide", // and hyphens, so use string literals
  "for": "all audiences", // for is a reserved word, so quote
  author: { // The value of this property is
    firstname: "David", // itself an object. Note that
    surname: "Flanagan" // these property names are unquoted.
  }
};

2.3.枚举属性

除了for in以外,我们还有其他方法去枚举属性

js实用工具库:

Example 6-2. Object utility functions that enumerate properties
/*
* Copy the enumerable properties of p to o, and return o.
* If o and p have a property by the same name, o's property is overwritten.
* This function does not handle getters and setters or copy attributes.
*/
function extend(o, p) {
  for(prop in p) { // For all props in p.
    o[prop] = p[prop]; // Add the property to o.
  }
  return o;
}
/*
* Copy the enumerable properties of p to o, and return o.
* If o and p have a property by the same name, o's property is left alone.
* This function does not handle getters and setters or copy attributes.
*/
function merge(o, p) {
  for(prop in p) { // For all props in p.
    if (o.hasOwnProperty[prop]) continue; // Except those already in o.
      o[prop] = p[prop]; // Add the property to o.
  }
  return o;
}
/*
* Remove properties from o if there is not a property with the same name in p.
* Return o.
*/
function restrict(o, p) {
  for(prop in o) { // For all props in o
    if (!(prop in p)) delete o[prop]; // Delete if not in p
  }
  return o;
}
/*
* For each property of p, delete the property with the same name from o.
* Return o.
*/
function subtract(o,p) {
  for(prop in p) { // For all props in p
    delete o[prop]; // Delete from o (deleting a
    // nonexistent prop is harmless)
  }
  return o;
}
/*
* Return a new object that holds the properties of both o and p.
* If o and p have properties by the same name, the values from o are used.
*/
function union(o,p) { return extend(extend({},o), p); }
/*
* Return a new object that holds only the properties of o that also appear
* in p. This is something like the intersection of o and p, but the values of
* the properties in p are discarded
*/
function intersection(o,p) { return restrict(extend({}, o), p); }
/*
* Return an array that holds the names of the enumerable own properties of o.
*/
function keys(o) {
  if (typeof o !== "object") throw TypeError(); // Object argument required
  var result = []; // The array we will return
  for(var prop in o) { // For all enumerable properties
    if (o.hasOwnProperty(prop)) // If it is an own property
    result.push(prop); // add it to the array.
  }
  return result; // Return the array.
}
hasOwnProperty是自有属性

Object.keys()  //数组:[可枚举的自有属性的名称]

Object.getOwnPropertyNames()//数组:[自由属性的名称]

2.4.属性的特性

数据属性和存取器属性

数据属性的4个特性:value,writable,enumerable,configurable

存取器属性的4个特性:get,set,enumerable,configurable

属性描述符property descriptor

Object.getOwnPropertyDescriptor()可以获得某个对象特定属性的属性描述符

Object.defineProperty()可以设置属性的特性

新版本的extend方法:考虑了复制属性的特性,也考虑了复制存取器属性的getter和setter方法

/*
* Add a nonenumerable extend() method to Object.prototype.
* This method extends the object on which it is called by copying properties
* from the object passed as its argument. All property attributes are
* copied, not just the property value. All own properties (even non-
* enumerable ones) of the argument object are copied unless a property
* with the same name already exists in the target object.
*/
Object.defineProperty(Object.prototype,
  "extend", // Define Object.prototype.extend
{
  writable: true,
  enumerable: false, // Make it nonenumerable
  configurable: true,
  value: function(o) { // Its value is this function
    // Get all own props, even nonenumerable ones
    var names = Object.getOwnPropertyNames(o);
    // Loop through them
    for(var i = 0; i < names.length; i++) {
      // Skip props already in this object
      if (names[i] in this) continue;
      // Get property description from o
      var desc = Object.getOwnPropertyDescriptor(o,names[i]);
      // Use it to create property on this
      Object.defineProperty(this, names[i], desc);
    }
  }
});

2.5.对象的三个属性(object attribute)

prototype

class

extensible

2.5.1.prototype attribute(原型属性,很多时候简称为原型)

Object.getPrototyoeOf()

isPrototypeOf()用来检测一个对象是否是另外一个对象的原型

> var p = {x:1}; // Define a prototype object.
undefined
> var o = Object.create(p); // Create an object with that prototype.
undefined
> p.isPrototypeOf(o) // => true: o inherits from p
true
> Object.prototype.isPrototypeOf(o) // => true: p inherits from Object.prototype
true
> Object.isPrototypeOf(o) // => true: p inherits from Object.prototype
false
>

isPrototypeOf()函数实现的功能和instanceof运算符非常类似

2.5.2.class attribute(类属性)

function classof(o) {
  if (o === null) return "Null";
  if (o === undefined) return "Undefined";
  return Object.prototype.toString.call(o).slice(8,-1);
}

上面使用了Function.call()方法,就可以保证使用的toString不是被重写的。

原始的toString()方法返回如下格式的信息:

[object class]

classof(null) // => "Null"
classof(1) // => "Number"
classof("") // => "String"
classof(false) // => "Boolean"
classof({}) // => "Object"
classof([]) // => "Array"
classof(/./) // => "Regexp"
classof(new Date()) // => "Date"
classof(window) // => "Window" (a client-side host object)
function f() {}; // Define a custom constructor
classof(new f()); // => "Object"

自定义类,没办法通过类属性来区分对象的类。

2.5.3.extensible 可扩展性

> var o = Object.seal(Object.create(Object.freeze({x:1}),
... {y: {value: 2, writable: true}}));
undefined
> o
{}
> o.x
1
> o.y
2
> Object.isSealed(o)
true
> Object.isFrozen(o)
false
>
> Object.isExtensible(o)
false
>

Object有几个函数比较有用:

Object.isExtensible()

Object.preventExtensions()

Object.seal()

Object.isSealed()

Object.freeze()

Object.isFrozen()

2.6.序列化对象

JSON.stringify(o)

JSON.parse(s)

JSON:javascript object notation  对象表示法

JSON是序列化时候使用的数据交换格式

但是JSON的语法是js的一个子集,它并不能表示js里的所有值。

函数,RegExp,Error对象和undefined值不能序列化和还原。

而且只能序列化对象可枚举的自有属性。

2.7.对象方法

所有的js对象都从Object.prototype继承属性。这些继承属性主要是方法。

hasOwnProperty()

propertyIsEnumerable()

isPrototypeOf()

create()

getPrototypeOf()

toString()

toLocaleString()

toJSON()

valueOf()

toString,valueOf和toJSON是自定义类经常要重写的几个方法。

抱歉!评论已关闭.