3.1 Numbers
不像很多的语言,javaScript不区分integer类型和浮点类型。所有的数字都用浮点类型。Javascript用64bit浮点类型来表示。
十六进制:
0xff // 15*16 + 15 = 255 (base 10)
八进制:
0377 // 3*64 + 7*8 + 7 = 255 (base 10)
数字的表示方法:
[digits][.digits][(E|e)[(+|-)]digits]
例如:
3.14
2345.789
.333333333333333333
6.02e23 // 6.02 × 10^23
1.4738223E-32 // 1.4738223 × 10^−32
infinity:
var zero = 0; // Regular zero
var negz = -0; // Negative zero
zero === negz // => true: zero and negative zero are equal
1/zero === 1/negz // => false: infinity and -infinity are not equal
3.1.5 Dates and Times
var then = new Date(2010, 0, 1); // The 1st day of the 1st month of 2010 var later = new Date(2010, 0, 1, // Same day, at 5:10:30pm, local time 17, 10, 30); var now = new Date(); // The current date and time var elapsed = now - then; // Date subtraction: interval in milliseconds later.getFullYear() // => 2010 later.getMonth() // => 0: zero-based months later.getDate() // => 1: one-based days later.getDay() // => 5: day of week. 0 is Sunday 5 is Friday. later.getHours() // => 17: 5pm, local time later.getUTCHours() // hours in UTC time; depends on timezone later.toString() // => "Fri Jan 01 2010 17:10:30 GMT-0800 (PST)" later.toUTCString() // => "Sat, 02 Jan 2010 01:10:30 GMT" later.toLocaleDateString() // => "01/01/2010" later.toLocaleTimeString() // => "05:10:30 PM" later.toISOString() // => "2010-01-02T01:10:30.000Z"; ES5 only
3.2 Text
3.2.4 Pattern Matching
var text = "testing: 1, 2, 3"; // Sample text var pattern = /\d+/g // Matches all instances of one or more digits pattern.test(text) // => true: a match exists text.search(pattern) // => 9: position of first match text.match(pattern) // => ["1", "2", "3"]: array of all matches text.replace(pattern, "#"); // => "testing: #, #, #" text.split(/\D+/); // => ["","1","2","3"]: split on non-digits
3.3 Boolean Values
默认代表false的:
undefined null 0 -0 NaN "" // the empty string
如果有下面的语句:
if (o !== null) ...
直接可以写成
if(o).....
3.4 null and undefined
我们经常使用null来表示一个变量没有值,null也是一个对象,这个对象代表"no object"
我们同样可以使用undefined来表示一个变量没有值,但是它是一个更深层次上的,它表示一个变量没有被初始化,或者这个变量根本就不存在在这个对象当中,同样可以表示一个方法没有返回值。
如果你使用typeof来操作undefined,它会返回undefined。
null和undefined都表示没有赋值,使用==来比较它们会返回true,使用严格的===可以区分出来它们。
你或许想使用undefined来表示系统级的异常,null来表示编程级别的异常,如果你想将它们变成参数传递给方法,那么这个方法最后使用null来做参数。
3.5 The Global Object
var global = this; // Define a global variable to refer to the global object
3.6 Wrapper Objects
Javascript对象是由许多值组成的,它们是名值对。
String不是对象,但是,为什么它可以使用属性呢?当我们引用String的时候,Javascript将String的值变成一个对象,就如:new String(s),对象继承了string的函数和属性引用。当属性被引用完毕的时候,对象将会被销毁。number和boolean是一个道理。看下面的代码:
var s = "test"; // Start with a string value. s.len = 4; // Set a property on it. var t = s.len; // Now query the property.
首先给变量s赋值为test,然后调用s.len,这时会创建一个String对象,将len的值设置为4,然后String对象被销毁。第三行代码,将s.len的值赋值给变量t,因为刚才的对象被销毁了,所以这个值是undefined。因为这次创建的String对象没有len这个属性。
==操作符对待变量和它的包装类一样,如果想区分它们可以使用===,typeof同样可以区分原始变量和类。
3.7 Immutable Primitive Values and Mutable Object References
我们无法改变原始类型,即使像改变一个数字的值。String也是同样,当我们改变String的值,其实原来的String还是原来的样子。
var s = "hello"; // Start with some lowercase text
s.toUpperCase(); // Returns "HELLO", but doesn't alter s
s // => "hello": the original string has not changed
原始类型比较相不相等,主要看它的值,如果值相同那么它们就是相同的,String比较的是String的长度,和每个位置的字符是否相等。
而Object是可变的,即使它们属性的值相等也不能算相等。数组也是同样,即使含有相同的元素。
Object我们有时候叫它们为引用类型,两个Object相等,只有它们的引用指向了同一个Object。
var a = []; // The variable a refers to an empty array. var b = a; // Now b refers to the same array. b[0] = 1; // Mutate the array referred to by variable b. a[0] // => 1: the change is also visible through variable a. a === b // => true: a and b refer to the same object, so they are equal.
3.8 Type Conversions
10 + " objects" // => "10 objects". Number 10 converts to a string
"7" * "4" // => 28: both strings convert to numbers
var n = 1 - "x"; // => NaN: string "x" can't convert to a number
n + " objects" // => "NaN objects": NaN converts to string "NaN"
3.8.1 Conversions and Equality
因为Javascript能自由的转化变量,它的==操作符也同样是灵活的。下面的都是true,例如:
null == undefined // These two values are treated as equal. "0" == 0 // String converts to a number before comparing. 0 == false // Boolean converts to number before comparing. "0" == false // Both operands convert to numbers before comparing.
===操作符不会先进行转化。
3.8.3 Object to Primitive Conversions
Object_to_boolean 返回的都是true 即使是new Boolean("false"),同样返回true
将一个object转换成String
1. 如果有toString函数,那么调用toString函数。
2. 如果没有toString函数,那么去找valueOf函数,如果返回一个原始类型,再将这个原始类型转换成String返回。
3. 如果这俩都没有,那么报typeError异常。
将一个object转换成数字:
与上面的过程差不多,只不过先调用valueOf函数。
例子:空的数组返回0,只有一个元素的数组返回这个数字。如果这个数组为空,那么valueOf返回Object,然后调用toString方法,返回空字符,然后空字符转化成0.如果只有一个数字,那么返回这个字符,然后转换成这个数字。
var now = new Date(); // Create a Date object
typeof (now + 1) // => "string": + converts dates to strings
typeof (now - 1) // => "number": - uses object-to-number conversion
now == now.toString() // => true: implicit and explicit string conversions
now > (now -1) // => true: > converts a Date to a number
3.9 Variable Declaration
javascript的函数范围意味着所有在函数内部的变量声明是在整个函数体都可见的。变量是可见的即使在声明之前。
var scope = "global"; function f() { console.log(scope); // Prints "undefined", not "global" var scope = "local"; // Variable initialized here, but defined everywhere console.log(scope); // Prints "local" }
你可能会想第一行的代码应该打印global,因为local变量还没有被执行,但是因为函数范围规则,这种情况没有发生。本地变量在整个函数体范围内被定义,表示global变量被隐藏了。尽管local变量被定义了,但是它没有被初始化知道被执行。
3.10.3 The Scope Chain
当一个函数被定义,它保存了将要生效的范围链。当函数被调用,它创建一个新的object来保存贝蒂变量,添加一个新的object到保存范围链中,创建一个新的,长久的链,它代表函数的调用范围。每次外部函数调用的时候,内部函数都会被定义一次,由于范围链在每次调用的时候都不同,内部函数在定义的时候都会不一样,内部函数的代码是一样的,但是范围链却不一样。
这个范围链的概念对于理解声明和closures非常有帮助。
4.1 Primary Expressions
1.23 // A number literal
"hello" // A string literal
/pattern/ // A regular expression literal
true // Evalutes to the boolean true value
false // Evaluates to the boolean false value
null // Evaluates to the null value
this // Evaluates to the "current" object
i // Evaluates to the value of the variable i.
sum // Evaluates to the value of the variable sum.
undefined // undefined is a global variable, not a keyword like null.
4.2 Object and Array Initializers
[] // An empty array: no expressions inside brackets means no elements
[1+2,3+4] // A 2-element array. First element is 3, second is 7
var matrix = [[1,2,3], [4,5,6], [7,8,9]];
var sparseArray = [1,,,,5];
Object initializer expressions
var p = { x:2.3, y:-1.2 }; // An object with 2 properties
var q = {}; // An empty object with no properties
q.x = 2.3; q.y = -1.2; // Now q has the same properties as p
object字面量可以被嵌套:
var rectangle = { upperLeft: { x: 2, y: 2 },
lowerRight: { x: 4, y: 5 } };
var side = 1;
var square = { "upperLeft": { x: p.x, y: p.y },
'lowerRight': { x: p.x + side, y: p.y + side}};
4.4 Property Access Expressions
expression . identifier
expression [ expression ]
var o = {x:1,y:{z:3}}; // An example object
var a = [o,4,[5,6]]; // An example array that contains the object
o.x // => 1: property x of expression o
o.y.z // => 3: property z of expression o.y
o["x"] // => 1: property x of object o
a[1] // => 4: element at index 1 of expression a
a[2]["1"] // => 6: element at index 1 of expression a[2]
a[0].x // => 1: property x of expression a[0]
4.5 Invocation Expressions
f(0) // f is the function expression; 0 is the argument expression.
Math.max(x,y,z) // Math.max is the function; x, y and z are the arguments.
a.sort() // a.sort is the function; there are no arguments.
4.6 Object Creation Expressions
new Object()
new Point(2,3)
如果没有参数的话:
new Object
new Date
4.8.1 The + Operator
如果其中有一个是object,那么就将它变成原始变量,Date object调用toString,其他的object调用valueOf函数,多数不含有有效的valueOf函数,所以调用toString。
如果有任何一个变成了string,那么另一个也变成String来进行运算。
否则都变成number,来进行运算。
1 + 2 // => 3: addition
"1" + "2" // => "12": concatenation
"1" + 2 // => "12": concatenation after number-to-string
1 + {} // => "1[object Object]": concatenation after object-to-string
true + true // => 2: addition after boolean-to-number
2 + null // => 2: addition after null converts to 0
2 + undefined // => NaN: addition after undefined converts to NaN
1 + 2 + " blind mice"; // => "3 blind mice"
1 + (2 + " blind mice"); // => "12 blind mice"
1 + 2 // Addition. Result is 3.
"1" + "2" // Concatenation. Result is "12".
"1" + 2 // Concatenation. 2 is converted to "2". Result is "12".
11 < 3 // Numeric comparison. Result is false.
"11" < "3" // String comparison. Result is true.
"11" < 3 // Numeric comparison. "11" converted to 11. Result is false.
"one" < 3 // Numeric comparison. "one" converted to NaN. Result is false.
4.9.3 The in Operator
var point = { x:1, y:1 }; // Define an object
"x" in point // => true: object has property named "x"
"z" in point // => false: object has no "z" property.
"toString" in point // => true: object inherits toString method
var data = [7,8,9]; // An array with elements 0, 1, and 2
"0" in data // => true: array has an element "0"
1 in data // => true: numbers are converted to strings
3 in data // => false: no element 3
4.9.4 The instanceof Operator
var d = new Date(); // Create a new object with the Date() constructor
d instanceof Date; // Evaluates to true; d was created with Date()
d instanceof Object; // Evaluates to true; all objects are instances of Object
d instanceof Number; // Evaluates to false; d is not a Number object
var a = [1, 2, 3]; // Create an array with array literal syntax
a instanceof Array; // Evaluates to true; a is an array
a instanceof Object; // Evaluates to true; all arrays are objects
a instanceof RegExp; // Evaluates to false; arrays are not regular expressions
4.12 Evaluation Expressions
javascript可以解释String到javascript代码,评价出它们的值,它使用全局范围的eval函数,如
eval("3+2") // => 5
eval里面如果使用x=1的语句,那么x这个变量的值将会被改变
4.13.3 The delete Operator
var o = { x: 1, y: 2}; // Start with an object
delete o.x; // Delete one of its properties
"x" in o // => false: the property does not exist anymore
var a = [1,2,3]; // Start with an array
delete a[2]; // Delete the last element of the array
a.length // => 2: array only has two elements now
var o = {x:1, y:2}; // Define a variable; initialize it to an object
delete o.x; // Delete one of the object properties; returns true
typeof o.x; // Property does not exist; returns "undefined"
delete o.x; // Delete a nonexistent property; returns true
delete o; // Can't delete a declared variable; returns false.
// Would raise an exception in strict mode.
delete 1; // Argument is not an lvalue: returns true
this.x = 1; // Define a property of the a global object without var
delete x; // Try to delete it: returns true in non-strict mode
// Exception in strict mode. Use 'delete this.x' instead
x; // Runtime error: x is not defined
第一步:在AndroidManifest.xml中添加
<provider android:name=".MyContentProvider" android:authorities="cn.edu.mytest"></provider>
第二步:继承ContentProvider
package cn.edu.database; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class MyContentProvider extends ContentProvider{ private MySqliteHelper helper; private static final UriMatcher MATCHER=new UriMatcher(UriMatcher.NO_MATCH);//Uri不匹配码,不匹配返回-1 private static final int PERSONS=1; private static final int PERSON=5; static { //类加载的时候执行,一般用来初始化静态变量 MATCHER.addURI("cn.edu.mytest", "person", PERSONS);//如果匹配这个Uri(content://cn.edu.test/person),返回PERSONS MATCHER.addURI("cn.edu.mytest", "person/#", PERSON); } public MyContentProvider() { helper=new MySqliteHelper(this.getContext(),"test.db",null,1); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub SQLiteDatabase db=helper.getWritableDatabase(); int num=0; switch(MATCHER.match(uri)){ case PERSONS: num=db.delete("product", selection, selectionArgs); return num; case PERSON: long rowid=ContentUris.parseId(uri); String where ="id="+rowid; num=db.delete("product", where, selectionArgs); return num; default: throw new IllegalArgumentException("this is unknown uri:"+uri); } } @Override public String getType(Uri uri) { // TODO Auto-generated method stub switch(MATCHER.match(uri)){ case PERSONS: return "vnd.android.cursor.dir/person";//返回是集合类型就是dir case PERSON: return "vnd.android.cursor.item/person"; default: throw new IllegalArgumentException("this is unknown uri:"+uri); } } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub SQLiteDatabase db=helper.getWritableDatabase(); switch(MATCHER.match(uri)){ case PERSONS: long rowid=db.insert("product", "name", values);//如果主键值是整形却增加,那么rowid就是主键值 Uri insertUri=ContentUris.withAppendedId(uri, rowid); this.getContext().getContentResolver().notifyChange(uri, null);//发错数据变化通知 return insertUri; default: throw new IllegalArgumentException("this is unknown uri:"+uri); } } @Override public boolean onCreate() {//该方法由操作系统调用,当内容提供者的实例被创建出来以后调用,只会被调用一次 // TODO Auto-generated method stub return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }
第三步:在其他的应用中访问ContentProvider
public void accessContentProvider()//该方法可以在其他应用程序中调用 { Uri uri=Uri.parse("content://cn.edu.mytest/person"); ContentResolver reslover=this.getContext().getContentResolver(); ContentValues values=new ContentValues(); values.put("name","zhangsan"); values.put("time", "2012"); reslover.insert(uri, values);//会调用ContentProvider中的insert() } public void accessContentProviderDelete()//该方法可以在其他应用程序中调用 { Uri uri=Uri.parse("content://cn.edu.mytest/person/1"); ContentResolver reslover=this.getContext().getContentResolver(); reslover.delete(uri,null,null); }
CotentProvider:可以把应用中的xml/txt/db/数据对外共享
使用ContentProvider可以统一数据的访问方式
写一个PersonProvider类继承ContentProvider
在配置清单中添加配置信息
<provider android:name=".PersonProvider"
android:authorities="cn.edu.personprovide(标志)>
Uri代表了要操作的数据,Uri主要包含了两部分信息:1、需要操作的ContentProvider,
2、对ContentProvider中的什么数据进行操作
括号代表注释
content:(这个是schema)//cn.edu.personprovide(要操作的主机名或者
authority)/person/10(person/1是路径,1是ID)
ContentProvider的schema已经由Android所规定,schema为:content//主机名(或叫
Authority)用于唯一标志这个Contentprovider,外部调用者可以根据这个标志来找到
它,路径可以用来表示我们要操作的数据,路径构建应根据业务而定
监听ContentProvider中数据的变化
A应用向ContentProvider中添加了一条数据
ContentProvidr发出数据变化通知B应用
在继承ContentProvider的类得inset方法中添加
this.getContext().getContentResolver().notifyChange(uri, null);//发出数据变
化通知
B应用要处于运行状态
在B应用的Activity的中onCreate方法中
this.getContentResolver().registerContentObserver(Uri,true,new
PersonContent());
private class PersonContentObserver extedns ContentObserver{
在onChange方法中()
{
Uri uri=Uri.prase("content://cn.edu.test/product");
getContentResolver.qeruy(uri,null,null,"personid desc limit 1");
}
}