When you initialize the variables name and income globally without the let, const or var they implicitly become properties of the global object in non strict mode.
Now in the class Person, the method print is defined. The class being run in strict mode implicitly, the this will be undefined always when you get the method reference from class instance:
let print = p1.getFunc();
In the above snippet the method reference is held in the print variable, but the this in the print function is undefined due to strict mode. So when you run the print it will throw an error.
From MDN:
When a static or prototype method is called without a value for this,
such as by assigning a variable to the method and then calling it, the
this value will be undefined inside the method. This behavior will be
the same even if the "use strict" directive isn't present, because
code within the class body's syntactic boundary is always executed in
strict mode.
In order to point this to the expected object you can use Function.prototype.bind to bind the expected this to the method reference:
name='sohan';
income=23232;
class Person{
    constructor(name,income)
    {
        this.name=name;
        this.income=income;
    }
    print(){
        console.log(this.name);
        console.log(this.income);
    }
    getFunc(){
        return this.print;
    }
}
let p1=new Person('bhavuk',10000);
let myPrint = p1.getFunc();
myPrint = myPrint.bind(p1);
myPrint();
//will pount to the global object where you declare the 2 properties
myPrint = p1.getFunc();
myPrint = myPrint.bind(globalThis);
myPrint();
//Will throw error as the this is undefined
myPrint = p1.getFunc();
myPrint();