Javascript TypeError:无法读取属性';toArray';在上下文中为空。<;匿名>;打字
当我尝试使用toArray函数创建一个新列表时,我一直遇到这样的错误“TypeError:cannotreadproperty'toArray'of null at Context” 我正在尝试创建一个链表实现。toArray函数不能更改,但我很确定问题必须出在reduce函数中,如果不是这样,那么可能是fromArray函数Javascript TypeError:无法读取属性';toArray';在上下文中为空。<;匿名>;打字,javascript,typescript,Javascript,Typescript,当我尝试使用toArray函数创建一个新列表时,我一直遇到这样的错误“TypeError:cannotreadproperty'toArray'of null at Context” 我正在尝试创建一个链表实现。toArray函数不能更改,但我很确定问题必须出在reduce函数中,如果不是这样,那么可能是fromArray函数 type Selector<T> = (head:T, rest?:Cons<T>)=> T|Cons<T>; type Con
type Selector<T> = (head:T, rest?:Cons<T>)=> T|Cons<T>;
type Cons<T> = (selector: Selector<T>) => T|Cons<T>;
function cons<T>(head:T, rest?: Cons<T>): Cons<T> {
return (selector: Selector<T>) => selector(head, rest);
}
function head<T>(list:Cons<T>):T {
return <T>list((head, rest?) => head);
}
function rest<T>(list:Cons<T>):Cons<T> {
return <Cons<T>>list((head, rest?) => rest);
}
function fromArray<T>(arr:T[]):Cons<T>{
function aux(array:T[], i:number):Cons<T>{
if(i<array.length){
return cons(array[i], aux(array.slice(i+1), i))
}
else{
return null
}
}
return aux(arr, 0);
}
function reduce<T>(f:(x:T, y:T)=>T, initial:T, list:any):T {
if(list){
return reduce(f, f(initial, head(list)), rest(list));
}
else{
return initial;
}
}
class List<T> {
private head: Cons<T>;
constructor(list: T[] | Cons<T>) {
if (list instanceof Array) {
this.head = fromArray(list);
} else {
this.head = list;
}
}
toArray(): T[] {
return reduce((a,t)=>(a.push(t), a), [], this.head).reverse();
}
type选择器=(head:T,rest?:Cons)=>T | Cons;
类型Cons=(选择器:选择器)=>T | Cons;
功能cons(头部:T,其余?:cons):cons{
返回(选择器:选择器)=>选择器(头部、休息);
}
功能负责人(列表:Cons):T{
返回列表((head,rest?=>head);
}
功能休息(列表:缺点):缺点{
返回列表((head,rest?=>rest);
}
函数fromArray(arr:T[]):Cons{
函数aux(数组:T[],i:编号):Cons{
if(iT,首字母:T,列表:any):T{
如果(列表){
返回减少(f,f(首字母,首字母(列表)),剩余字母(列表));
}
否则{
返回首字母;
}
}
班级名单{
私人负责人:犯人;
建造商(列表:T[]| Cons){
if(数组的列表实例){
this.head=fromArray(列表);
}否则{
this.head=列表;
}
}
toArray():T[]{
返回reduce((a,t)=>(a.push(t,a),[],this.head);
}
您应该打开strictNullChecks
编译器选项,因为有很多未定义的和null
在代码周围浮动,而不标记任何错误。这里的主要问题是,在您的实现中,空列表只是未定义的(或者可能是null
),并且您没有在足够的位置检查它。以下是我调试的结果;我不知道是否所有的bug都消失了,但是toArray()
现在似乎可以工作了。我在更改内容的地方添加了一些注释:
type Selector<T> = (head: T, rest?: Cons<T>) => T | Cons<T>;
// a list can be undefined, so I added it:
type Cons<T> = undefined | ((selector: Selector<T>) => T | Cons<T>);
function cons<T>(head: T, rest?: Cons<T>): Cons<T> {
return (selector: Selector<T>) => selector(head, rest);
}
// the head function is guaranteed to return a T only on a non-empty list,
// so I overloaded it:
function head(list: undefined): undefined;
function head<T>(list: Cons<T>): T;
function head<T>(list: Cons<T>): T | undefined {
if (!list) return; // watch out for empty list
return <T>list((head, rest?) => head);
}
function rest<T>(list: Cons<T>): Cons<T> {
if (!list) return; // watch out for empty list
return <Cons<T>>list((head, rest?) => rest);
}
function fromArray<T>(arr: T[]): Cons<T> {
function aux(array: T[], i: number): Cons<T> {
if (i < array.length) {
return cons(array[i], aux(array.slice(i + 1), i))
}
else {
return; // use undefined instead of null, easier this way
}
}
return aux(arr, 0);
}
// note that you want reduce to return a T[] instead of a T in toArray()
// that means your f cannot be (x:T, y:T) => T. Add a U parameter for the
// type of initial, return value, and the return type of f
function reduce<T, U>(f: (x: U, y: T) => U, initial: U, list: Cons<T>): U {
if (list) {
return reduce(f, f(initial, head(list)), rest(list));
}
else {
return initial;
}
}
class List<T> {
private head: Cons<T>;
constructor(list: T[] | Cons<T>) {
if (list instanceof Array) {
this.head = fromArray(list);
} else {
this.head = list;
}
}
toArray(): T[] {
// push puts things at the end; you're trying to cons, right?
// that's unshift
return reduce<T, T[]>((a, t) => (a.unshift(t), a), [], this.head).reverse();
}
}
type选择器=(head:T,rest?:Cons)=>T | Cons;
//列表可以是未定义的,所以我添加了它:
类型Cons=未定义的|((选择器:选择器)=>T | Cons);
功能cons(头部:T,其余?:cons):cons{
返回(选择器:选择器)=>选择器(头部、休息);
}
//head函数保证仅在非空列表上返回T,
//所以我超载了:
功能头(列表:未定义):未定义;
功能负责人(列表:Cons):T;
功能头(列表:Cons):T |未定义{
如果(!list)return;//注意空列表
返回列表((head,rest?=>head);
}
功能休息(列表:缺点):缺点{
如果(!list)return;//注意空列表
返回列表((head,rest?=>rest);
}
函数fromArray(arr:T[]):Cons{
函数aux(数组:T[],i:编号):Cons{
if(iT。为
//初始类型、返回值和f的返回类型
函数reduce(f:(x:U,y:T)=>U,首字母:U,列表:Cons):U{
如果(列表){
返回减少(f,f(首字母,首字母(列表)),剩余字母(列表));
}
否则{
返回首字母;
}
}
班级名单{
私人负责人:犯人;
建造商(列表:T[]| Cons){
if(列出数组的实例){
this.head=fromArray(列表);
}否则{
this.head=列表;
}
}
toArray():T[]{
//推把事情推到最后,你是在试图欺骗,对吗?
//那是不可移动的
返回reduce((a,t)=>(a.unshift(t),a),[],this.head.reverse();
}
}
希望这会有所帮助;祝你好运!你怎么称呼这个方法?你能重现这个问题吗?只需稍加修改,你的reduce函数就可以进行类型检查并工作了。