typerscript学习总结二

1、this
this在JavaScript里总是指向调用者,这点经常容易导致被坑,在ES6之前经常需要类似var self = this来把this保存下来。
ES6和TypeScript针对这点做了改进,使用箭头函数可以把创建函数时的this自动保存下来。
let permission = {
    name: 'brook',

    checkLogin: function() {
        return function() {
            console.info(this.name === 'brook');
        }
    }
};

permission.checkLogin()(); // 出错, this为undefined

let permission = {
    name: 'brook',

    checkLogin: function() {
        return () => {
            console.info(this.name === 'brook');
        }
    }
};

permission.checkLogin()(); // 通过,因为用了箭头函数
不过上面的this还是有个缺点,得到的this是any类型,这样重构起来会不方便,这时可以用this参数来改进:
this参数只是一种定义,使用时是不需要传的。
interface Permission{
    name: string;
    checkLogin(this: Permission): ()=>void;
}

let permission: Permission = {
    name: 'brook',

    checkLogin: function(this: Permission) {
        return () => {
            console.info(this.name === 'brook'); //这里的this不是any,而是Permission
        }
    }
};
permission.checkLogin()();
这样也倒逼着定义好类型,发挥TypeScript强类型的优势。

2、使用let声明变量
let主要是对var的一个代替,用let更符合人思考的过程,这才和C#var的功能是差不多。
let的用法和var是一样的:
let str = 'string';
let的作用域是块级作用域,比如上面的循环,用let声明i的话就可心得到期望的值
for (let i = 0; i < 10; i++) {
    setTimeout(function() { console.info(i); }, 100);
}
这里得到的结果就是0, 1, 2....9。
所以建议还是抛弃var,选择let。


3、类
同C#一样,由构造函数,属性,方法组成,属性和方法有三个级别的访问权限:private, protected, public,比C#少个internal。
不过不同的是C#类的成员默认是private,而TypeScript默认是public。
在类里面所有成员都必须用this来访问。
class User{
    constructor(name: string, pwd: string){
        this.name = name;
        this.pwd = pwd;
    }

    name: string;
    private pwd: string;

    checkLogin(): boolean{
        return this.name === 'brook' && this.pwd === '123';
    }
}

let u: User = new User('brook', '123');
console.info(u.checkLogin()); // true

u.name = 'test';
console.info(u.checkLogin()); // false


5、静态属性和方法
上面说的都是实例成员,TypeScript也支持静态成员,不用实例化,而是通过类名来访问。
class User{
    static permission = 'user';

    static setPermission(p: string){
        User.permission = p;
    }
}

console.info(User.permission); // user

User.setPermission('admin');
console.info(User.permission); // admin


6、泛型
同接口一样支持泛型,用法也一样,可以参考接口泛型。
interface Testable<T> {
    field: T;
    method(arg: T): T;
}

class Test<T> implements Testable<T>{
    field: T;
    method(arg: T): T{
        console.info(`arg is ${typeof arg}`);
        return null;
    }
}

let test11 = new Test<string>();
test11.method('method');  // arg is string
test11.method(123); // error, 123 is not string
总的来说,TypeScript的类和C#或Java可以说十分相似,除了兼容性基本上没有什么新的东西,不过对于JavaScript来说却是一大进步了。


9、数值
C#的数字类型有好几种:int, long, float, double, byte等,而TypeScript和JavaScript一样,所有的数字都是浮点数,都是用number表示,这样也省了很了事,少了C#里类似long转int overflow问题。
下面用不同进制方式显示数字20。
let num = 20;       // 10进制
let num = 0xa4;     // 16进制
let num = 0b10010;  // 2进制
let num = 0o24;     // 8进制


10、枚举
enum,大家都知道javascript没有enum,这也是TypeScript为此作的补充。功能上和C#差不多:
1.    目的都是为数值提供一个友好的名字,增加代码可读性和可重构性
2.    默认情况下从0开始编号
3.    也可以手动赋值
4.    可以实现类似C# Flag特性
但也有一些细节不一样:
5.    C#的枚举值toString()会返回枚举的文本值,而TypeScript是数值
6.    TypeScript可以通过数值下标取得枚举字符串值
enum Action{
    add = 1,
    edit = 2,
    del = 4,
    all = add | edit | del
}

console.info(Action.add);  // 返回1
console.info(Action.add.toString());  // 返回1
console.info(Action[1]);  // 返回"add"
console.info(Action[3]);  // 返回undefined
console.info(Action.all); // 返回7
console.info(Action.all & Action.add) //返回1
上面的Action编译成JavaScript的结果:
var Action;
(function (Action) {
    Action[Action["add"] = 1] = "add";
    Action[Action["edit"] = 2] = "edit";
    Action[Action["del"] = 4] = "del";
    Action[Action["all"] = 7] = "all";
})(Action || (Action = {}));

11、any
这个和C#的dynamic很相似,可以代表任何东西且在上面调用方法或属性不会在编译时期报错,当然也本来就是JavaScript最基本的东西。
let test: any = 'test';
test = false;

test.test(); //编译时期不会有报错
let arr: any[] = ['test', false];


12、void、null、undefined和never
void和C#的一样,表示没有任何东西。
null和undefined和JavaScript一样,分别就是它们自己的类型,个人觉得这两者功能有点重合,建议只使用undefined。
never是TypeScript引进的,个人觉得是一种语义上的类型,用来表示永远不会得到返回值,比如while(true){}或throw new Error()之类。
function test(): void{} //  void
let a: string = null; let b: null = null; // null有自己的类型,并且默认可以赋值给任何类型(除never之外),可用--strictNullChecks标记来限制这个功能
let a: string = undefined;  let b: undefined = undefined; // undefined, 同上
function error(): never{ // never
    throw new Error('error');
}


13、数组
有基本的数组:
let arr: string[] = ['a', 'b', 'c'];
也有类似C#的泛型List
let list: Array<string> = ['a', 'b', 'c'];
数组功能没C#配合linq那么强大,不过配合其他一些库如lodash也可以很方便的进行各种操作。
数组还可以利用扩展操作符...来把数组解开再放入其他数组中。
let arr: number[] = [1, 2, 3];
let newArr: number[] = [...arr, 4, 5];
console.info(newArr); // 1, 2, 3, 4, 5


13、//匿名类;声明一个类#3.0,相当于把类初始化和对象声明放在一起
            var news = new { title="特大喜讯",author="夕阳眼",postdate="3013-10-9",msg="今晚公布"};


15、C#之初始化器和匿名类
对象初始化器:实例化一个对象的时候给其属性赋值
People p=new People{Id=1,Name=”test”,Age=12};
当然对象初始化器可以给部分属相赋值
集合初始化器的例子
List<Peolpe> p =new List<People>{new People{Id=1,Name=”test”,Age=12},

new People{Id=1,Name=”test”,Age=12},

new People{Id=1,Name=”test”,Age=12}};
 
其他类型的初始器
数组使用初始化器:
string [] test={“a”,”b”,”c”};
匿名类型使用初始化器:
var test=new {Title=“a”,author=”b”};
字典使用初始化器:
Dictionary<string,int> test=new Dictionary<string,int>(){{“A”,”1”},{“b”,12}}

***************** C#:匿名类型*****************
C#:匿名类型

当我们想要在代码中创建一个对象,需要用 new Object()  来创建,如果这个对象里面有一些 属性我们想要在 new 时就初始化,那么我们会重写 一个构造函数。

如果不想重写一个 构造函数 该如何做?
例子如下:
自定义一个类 Point.cs
    class Point
    {
        public int x;
        public int y;
        
        //public Point(int sx , int sy){
        //    x = sx;
        //    y = sy;
        //}
    }
如果不想写上面 带初始化x,y的构造函数该如何做?
我们只需在 使用 Point的地方,用下面的代码即可:
            Point p = new Point {
                x = 5 , 
                y = 5
            };
//或
            Point p1 = new Point {
                x = 5
            };
//或
            Point py = new Point {
                y = 5
            };
是不是很方便,你可以在使用Point的地方随意初始化任何一个属性,而不用写多个 构造函数。
1.如果在代码中我们会经常调用一些 变量 的值,通常会 把它统一存在 一个类中,然后把该变量的属性设置为 static。但是我们可以创建一个匿名类型,来简化使用。
例子如下:
    class Help
    {
        public static int zero = 0;
        public static double PI = 3.14;
        
    }
使用时如下:
            int z = Help.zero;
            double pi = Help.PI;
用匿名类型简化,不用多余创建一个类。
            //不用给属性设置类型,自动判断属性类型
            //属性的名称就是匿名对象中属性的名称
            //匿名对象的类型不知,只知道匿名对象的名称是 nmbject
            var nmbject = new {
                ZERO = 0,
                PI = 3.14 ,
                Name = "LIUYAN"
            };
            
            //调用 常用的值
            double b = nmbject.PI;
            //nmbject.PI = 2.1;  这个是错的,匿名类型是只读的,所以想要修改属性,就不能设为匿名类型
 
            //匿名对象也可以为数组
            //属性名称必须完全一样,才代表是同一种匿名类型
            var nmbjectArray = new[] {
                new{
                PI = 3.14,
                Name = "LIUYAN"
                },
                new{
                PI = 3.15,
                Name = "LIUYAN2"
                },

 

***************** C#:匿名类型(结束)*****************


15、关于js匿名类
    var  class1={p1:value1,p2:value2};
    这个也可以写成
    var class1={};
     class1.p1=value1;
     class1.p2=value2;
首先所有的匿名类都是继承与Object核心对象的var class1={} 意味着实例化了一个Object对象,它拥有Object对象的原生属性和原生方法。
但是你不能为匿名类添加原生方法,例如这样写是错误的:
class1.prototype.func1=function(){};
你也不能尝试用new() 方法来构造一个新的与class1有相同的属性的新对象,因为它已经实例化了。以下写法也是错的:
var classB=new classA();
这是无法构造的,
准确的说,匿名类实际上是继承与Object的某一个半实例,相当于C#中的静态类。你可以为他添加方法和属性
例如:
class1.func1=function(){}
调用的时候就这样:
class1.func1();  酷似C#中的静态类
但是你可以为Object添加原生函数,这样你的匿名类(实际上是所有的类)都有这个方法
例如:
var class1={};
class1.p1=value1;
class1.p2=value2;
Object.prototype.func1=function(){  alert("1")  };
class1.func1();
是没有问题的,但是这样一来,所有的实例化对象都有了func1()方法。实际应用中应该避免给Object类添加原生方法。

20、JavaScript处理JSON:https://www.cnblogs.com/JoannaQ/p/3190879.html
①遍历JSON对象
 
myJson = {"name":"nikita", "password":"1111"};
for(var p in myJson){//遍历json对象的每个key/value对,p为key
   alert(p + " " + myJson[p]);
}
②遍历JSON数组
 
 
packJson = [
    {"name":"nikita", "password":"1111"},
    {"name":"tony", "password":"2222"}
];

for(var p in packJson){//遍历json数组时,这么写p为索引,0,1
   alert(packJson[p].name + " " + packJson[p].password);
}

*****************json对象和js对象的区别***************

1、json 是一种轻量级的数据交换格式。json对象 可以理解成 符合 json格式规范 的对象,对于 js 来说,它就是一个普通的对象,没有什么区别。
JSON与JS对象的区别
和一些同学一样:总是感觉json对象(其实json不是对象)和js对象的字面量表示法相同,最近学习json,真心搞不懂,js对象和json有什么区别?就是感觉json的key要用” “括起来,但是js对象的字面量表示法不需要。 
比如:
//js对象的字面量表示法: 
var people1={ 
name:'hehe', 
age:18 
}; 

//json的格式是: 
var people1={ 
"name":'hehe', 
"age":18 
}; 


二者相同的地方是,看起来都是数据,而且恰巧又都是文本;不同的地方在于,JS字面量的文本是被脚本引擎直接解析的,而JSON的文本,如果要转化为JS对象的话,是交给eval函数来处理的,那么,如何理解JSON的文本,就取决于这个函数,而不是脚本引擎,因为这2者的处理根本就不在一个层面上。 

一直以为JSON是对象,然而在阅读js高程中出现了一些不理解的地方,网上查阅才发现JSON与JS有很大的不同。 

var obj={width:100,height:200},这样的并不叫JSON,并且JSON只是一种数据格式,并不是具体的实例对象。但很多人把这样的JS对象当成JSON。 

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,JSON格式的数据,主要是为了跨平台交流数据用的。 

但JSON和JavaScript确实存在渊源,可以说这种数据格式是从JavaScript对象中演变出来的,它是JavaScript的一个子集。JSON本身的意思就是JavaScript对象表示法(JavaScript Object Notation),它用严格的JavaScript对象表示法来表示结构化的数据。 

它是一种严格的js对象的格式,JSON的属性名必须有双引号,如果值是字符串,也必须是双引号; 

JSON只是一种数据格式(或者叫数据形式),数据格式其实就是一种规范,格式、形式、规范是不能用来存诸数据的。我们不能把以下的对象叫JSON,比如: 

<script>

var obj2={};//这只是JS对象

var obj3={width:100,height:200};/*这跟JSON就更不沾边了,只是JS的对象 */

var obj4={'width':100,'height':200};/*这跟JSON就更不沾边了,只是JS的对象 */

var obj5={"width":100,"height":200,"name":"rose"}; /*我们可以把这个称做:JSON格式的JavaScript对象 */

var str1='{"width":100,"height":200,"name":"rose"}';/*我们可以把这个称做:JSON格式的字符串 */

var a=[

{"width":100,"height":200,"name":"rose"},

{"width":100,"height":200,"name":"rose"},

{"width":100,"height":200,"name":"rose"},

];

/*这个叫JSON格式的数组,是JSON的稍复杂一点的形式 */

var str2='['+

'{"width":100,"height":200,"name":"rose"},'+

'{"width":100,"height":200,"name":"rose"},'+

'{"width":100,"height":200,"name":"rose"},'+

']' ;

/*  这个叫稍复杂一点的JSON格式的字符串  */ 
</script>

*****************json对象和js对象的区别(结束)***************

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值